Compare commits
	
		
			47 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5aa15c51ec | ||
| 
						 | 
					a8aedd9cf3 | ||
| 
						 | 
					b851b632bc | ||
| 
						 | 
					541e07fb65 | ||
| 
						 | 
					6ad16a897d | ||
| 
						 | 
					72f1053a93 | ||
| 
						 | 
					fb15a2762c | ||
| 
						 | 
					9165248b91 | ||
| 
						 | 
					add18b29db | ||
| 
						 | 
					1971653548 | ||
| 
						 | 
					392cd64d7b | ||
| 
						 | 
					b5affbb7c8 | ||
| 
						 | 
					71d1206277 | ||
| 
						 | 
					26e6a8c409 | ||
| 
						 | 
					eb54fae11a | ||
| 
						 | 
					ee773e5966 | ||
| 
						 | 
					7218ccdba8 | ||
| 
						 | 
					332400e48a | ||
| 
						 | 
					ad1a5d3702 | ||
| 
						 | 
					3006b4184d | ||
| 
						 | 
					84eb84a080 | ||
| 
						 | 
					60beea548b | ||
| 
						 | 
					5f9c149e59 | ||
| 
						 | 
					53367c6f04 | ||
| 
						 | 
					d7f817ee44 | ||
| 
						 | 
					d33a87da54 | ||
| 
						 | 
					3aebfb12b7 | ||
| 
						 | 
					1d6c55ffa6 | ||
| 
						 | 
					5e7080aac3 | ||
| 
						 | 
					fad739bc01 | ||
| 
						 | 
					c6b7f23884 | ||
| 
						 | 
					a6f7e446de | ||
| 
						 | 
					89d95d3ae1 | ||
| 
						 | 
					764208698f | ||
| 
						 | 
					57129cf934 | ||
| 
						 | 
					aae1a842d5 | ||
| 
						 | 
					623f35aec7 | ||
| 
						 | 
					870bf842cf | ||
| 
						 | 
					07f2d7dd5c | ||
| 
						 | 
					f223f2edc5 | ||
| 
						 | 
					e848a9a577 | ||
| 
						 | 
					7569d98e07 | ||
| 
						 | 
					596dee2f24 | ||
| 
						 | 
					8eb27b5875 | ||
| 
						 | 
					d1457b312b | ||
| 
						 | 
					c9dd2af196 | ||
| 
						 | 
					827cfe4e8f | 
@@ -211,6 +211,7 @@ def agent_outages_task() -> None:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    agents = Agent.objects.only(
 | 
					    agents = Agent.objects.only(
 | 
				
			||||||
        "pk",
 | 
					        "pk",
 | 
				
			||||||
 | 
					        "agent_id",
 | 
				
			||||||
        "last_seen",
 | 
					        "last_seen",
 | 
				
			||||||
        "offline_time",
 | 
					        "offline_time",
 | 
				
			||||||
        "overdue_time",
 | 
					        "overdue_time",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -213,7 +213,8 @@ class TestAPIv3(TacticalTestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # setup data
 | 
					        # setup data
 | 
				
			||||||
        agent = baker.make_recipe("agents.agent")
 | 
					        agent = baker.make_recipe("agents.agent")
 | 
				
			||||||
        task = baker.make("autotasks.AutomatedTask", agent=agent)
 | 
					        script = baker.make_recipe("scripts.script")
 | 
				
			||||||
 | 
					        task = baker.make("autotasks.AutomatedTask", agent=agent, script=script)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        url = f"/api/v3/{task.pk}/{agent.agent_id}/taskrunner/"  # type: ignore
 | 
					        url = f"/api/v3/{task.pk}/{agent.agent_id}/taskrunner/"  # type: ignore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -321,11 +321,16 @@ class CheckRunner(APIView):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def patch(self, request):
 | 
					    def patch(self, request):
 | 
				
			||||||
        check = get_object_or_404(Check, pk=request.data["id"])
 | 
					        check = get_object_or_404(Check, pk=request.data["id"])
 | 
				
			||||||
 | 
					        if pyver.parse(check.agent.version) < pyver.parse("1.5.7"):
 | 
				
			||||||
 | 
					            return notify_error("unsupported")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        check.last_run = djangotime.now()
 | 
					        check.last_run = djangotime.now()
 | 
				
			||||||
        check.save(update_fields=["last_run"])
 | 
					        check.save(update_fields=["last_run"])
 | 
				
			||||||
        status = check.handle_checkv2(request.data)
 | 
					        status = check.handle_check(request.data)
 | 
				
			||||||
 | 
					        if status == "failing" and check.assignedtask.exists():  # type: ignore
 | 
				
			||||||
 | 
					            check.handle_assigned_task()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return Response(status)
 | 
					        return Response("ok")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CheckRunnerInterval(APIView):
 | 
					class CheckRunnerInterval(APIView):
 | 
				
			||||||
@@ -378,9 +383,18 @@ class TaskRunner(APIView):
 | 
				
			|||||||
                    )
 | 
					                    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # get last line of stdout
 | 
					                # get last line of stdout
 | 
				
			||||||
                value = new_task.stdout.split("\n")[-1].strip()
 | 
					                value = (
 | 
				
			||||||
 | 
					                    new_task.stdout
 | 
				
			||||||
 | 
					                    if task.collector_all_output
 | 
				
			||||||
 | 
					                    else new_task.stdout.split("\n")[-1].strip()
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if task.custom_field.type in ["text", "number", "single", "datetime"]:
 | 
					                if task.custom_field.type in [
 | 
				
			||||||
 | 
					                    "text",
 | 
				
			||||||
 | 
					                    "number",
 | 
				
			||||||
 | 
					                    "single",
 | 
				
			||||||
 | 
					                    "datetime",
 | 
				
			||||||
 | 
					                ]:
 | 
				
			||||||
                    agent_field.string_value = value
 | 
					                    agent_field.string_value = value
 | 
				
			||||||
                    agent_field.save()
 | 
					                    agent_field.save()
 | 
				
			||||||
                elif task.custom_field.type == "multiple":
 | 
					                elif task.custom_field.type == "multiple":
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.2.1 on 2021-05-29 03:26
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('autotasks', '0021_alter_automatedtask_custom_field'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='automatedtask',
 | 
				
			||||||
 | 
					            name='collector_all_output',
 | 
				
			||||||
 | 
					            field=models.BooleanField(default=False),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -104,6 +104,7 @@ class AutomatedTask(BaseAuditModel):
 | 
				
			|||||||
    task_type = models.CharField(
 | 
					    task_type = models.CharField(
 | 
				
			||||||
        max_length=100, choices=TASK_TYPE_CHOICES, default="manual"
 | 
					        max_length=100, choices=TASK_TYPE_CHOICES, default="manual"
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					    collector_all_output = models.BooleanField(default=False)
 | 
				
			||||||
    run_time_date = DateTimeField(null=True, blank=True)
 | 
					    run_time_date = DateTimeField(null=True, blank=True)
 | 
				
			||||||
    remove_if_not_scheduled = models.BooleanField(default=False)
 | 
					    remove_if_not_scheduled = models.BooleanField(default=False)
 | 
				
			||||||
    run_asap_after_missed = models.BooleanField(default=False)  # added in agent v1.4.7
 | 
					    run_asap_after_missed = models.BooleanField(default=False)  # added in agent v1.4.7
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -68,6 +68,12 @@ class TaskRunnerGetSerializer(serializers.ModelSerializer):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class TaskGOGetSerializer(serializers.ModelSerializer):
 | 
					class TaskGOGetSerializer(serializers.ModelSerializer):
 | 
				
			||||||
    script = ScriptCheckSerializer(read_only=True)
 | 
					    script = ScriptCheckSerializer(read_only=True)
 | 
				
			||||||
 | 
					    script_args = serializers.SerializerMethodField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_script_args(self, obj):
 | 
				
			||||||
 | 
					        return Script.parse_script_args(
 | 
				
			||||||
 | 
					            agent=obj.agent, shell=obj.script.shell, args=obj.script_args
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = AutomatedTask
 | 
					        model = AutomatedTask
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
import asyncio
 | 
					 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import string
 | 
					import string
 | 
				
			||||||
@@ -14,9 +13,7 @@ from django.core.validators import MaxValueValidator, MinValueValidator
 | 
				
			|||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from logs.models import BaseAuditModel
 | 
					from logs.models import BaseAuditModel
 | 
				
			||||||
from loguru import logger
 | 
					from loguru import logger
 | 
				
			||||||
from packaging import version as pyver
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .utils import bytes2human
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger.configure(**settings.LOG_CONFIG)
 | 
					logger.configure(**settings.LOG_CONFIG)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -318,7 +315,7 @@ class Check(BaseAuditModel):
 | 
				
			|||||||
    def add_check_history(self, value: int, more_info: Any = None) -> None:
 | 
					    def add_check_history(self, value: int, more_info: Any = None) -> None:
 | 
				
			||||||
        CheckHistory.objects.create(check_history=self, y=value, results=more_info)
 | 
					        CheckHistory.objects.create(check_history=self, y=value, results=more_info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_checkv2(self, data):
 | 
					    def handle_check(self, data):
 | 
				
			||||||
        from alerts.models import Alert
 | 
					        from alerts.models import Alert
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # cpuload or mem checks
 | 
					        # cpuload or mem checks
 | 
				
			||||||
@@ -349,9 +346,6 @@ class Check(BaseAuditModel):
 | 
				
			|||||||
        elif self.check_type == "diskspace":
 | 
					        elif self.check_type == "diskspace":
 | 
				
			||||||
            if data["exists"]:
 | 
					            if data["exists"]:
 | 
				
			||||||
                percent_used = round(data["percent_used"])
 | 
					                percent_used = round(data["percent_used"])
 | 
				
			||||||
                total = bytes2human(data["total"])
 | 
					 | 
				
			||||||
                free = bytes2human(data["free"])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if self.error_threshold and (100 - percent_used) < self.error_threshold:
 | 
					                if self.error_threshold and (100 - percent_used) < self.error_threshold:
 | 
				
			||||||
                    self.status = "failing"
 | 
					                    self.status = "failing"
 | 
				
			||||||
                    self.alert_severity = "error"
 | 
					                    self.alert_severity = "error"
 | 
				
			||||||
@@ -365,7 +359,7 @@ class Check(BaseAuditModel):
 | 
				
			|||||||
                else:
 | 
					                else:
 | 
				
			||||||
                    self.status = "passing"
 | 
					                    self.status = "passing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                self.more_info = f"Total: {total}B, Free: {free}B"
 | 
					                self.more_info = data["more_info"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                # add check history
 | 
					                # add check history
 | 
				
			||||||
                self.add_check_history(100 - percent_used)
 | 
					                self.add_check_history(100 - percent_used)
 | 
				
			||||||
@@ -381,12 +375,7 @@ class Check(BaseAuditModel):
 | 
				
			|||||||
            self.stdout = data["stdout"]
 | 
					            self.stdout = data["stdout"]
 | 
				
			||||||
            self.stderr = data["stderr"]
 | 
					            self.stderr = data["stderr"]
 | 
				
			||||||
            self.retcode = data["retcode"]
 | 
					            self.retcode = data["retcode"]
 | 
				
			||||||
            try:
 | 
					            self.execution_time = "{:.4f}".format(data["runtime"])
 | 
				
			||||||
                # python agent
 | 
					 | 
				
			||||||
                self.execution_time = "{:.4f}".format(data["stop"] - data["start"])
 | 
					 | 
				
			||||||
            except:
 | 
					 | 
				
			||||||
                # golang agent
 | 
					 | 
				
			||||||
                self.execution_time = "{:.4f}".format(data["runtime"])
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if data["retcode"] in self.info_return_codes:
 | 
					            if data["retcode"] in self.info_return_codes:
 | 
				
			||||||
                self.alert_severity = "info"
 | 
					                self.alert_severity = "info"
 | 
				
			||||||
@@ -422,22 +411,8 @@ class Check(BaseAuditModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # ping checks
 | 
					        # ping checks
 | 
				
			||||||
        elif self.check_type == "ping":
 | 
					        elif self.check_type == "ping":
 | 
				
			||||||
            output = data["output"]
 | 
					            self.status = data["status"]
 | 
				
			||||||
 | 
					            self.more_info = data["output"]
 | 
				
			||||||
            if pyver.parse(self.agent.version) <= pyver.parse("1.5.2"):
 | 
					 | 
				
			||||||
                # DEPRECATED
 | 
					 | 
				
			||||||
                success = ["Reply", "bytes", "time", "TTL"]
 | 
					 | 
				
			||||||
                if data["has_stdout"]:
 | 
					 | 
				
			||||||
                    if all(x in output for x in success):
 | 
					 | 
				
			||||||
                        self.status = "passing"
 | 
					 | 
				
			||||||
                    else:
 | 
					 | 
				
			||||||
                        self.status = "failing"
 | 
					 | 
				
			||||||
                elif data["has_stderr"]:
 | 
					 | 
				
			||||||
                    self.status = "failing"
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                self.status = data["status"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.more_info = output
 | 
					 | 
				
			||||||
            self.save(update_fields=["more_info"])
 | 
					            self.save(update_fields=["more_info"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.add_check_history(
 | 
					            self.add_check_history(
 | 
				
			||||||
@@ -446,41 +421,8 @@ class Check(BaseAuditModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # windows service checks
 | 
					        # windows service checks
 | 
				
			||||||
        elif self.check_type == "winsvc":
 | 
					        elif self.check_type == "winsvc":
 | 
				
			||||||
            svc_stat = data["status"]
 | 
					            self.status = data["status"]
 | 
				
			||||||
            self.more_info = f"Status {svc_stat.upper()}"
 | 
					            self.more_info = data["more_info"]
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if data["exists"]:
 | 
					 | 
				
			||||||
                if svc_stat == "running":
 | 
					 | 
				
			||||||
                    self.status = "passing"
 | 
					 | 
				
			||||||
                elif svc_stat == "start_pending" and self.pass_if_start_pending:
 | 
					 | 
				
			||||||
                    self.status = "passing"
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    if self.agent and self.restart_if_stopped:
 | 
					 | 
				
			||||||
                        nats_data = {
 | 
					 | 
				
			||||||
                            "func": "winsvcaction",
 | 
					 | 
				
			||||||
                            "payload": {"name": self.svc_name, "action": "start"},
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        r = asyncio.run(self.agent.nats_cmd(nats_data, timeout=32))
 | 
					 | 
				
			||||||
                        if r == "timeout" or r == "natsdown":
 | 
					 | 
				
			||||||
                            self.status = "failing"
 | 
					 | 
				
			||||||
                        elif not r["success"] and r["errormsg"]:
 | 
					 | 
				
			||||||
                            self.status = "failing"
 | 
					 | 
				
			||||||
                        elif r["success"]:
 | 
					 | 
				
			||||||
                            self.status = "passing"
 | 
					 | 
				
			||||||
                            self.more_info = f"Status RUNNING"
 | 
					 | 
				
			||||||
                        else:
 | 
					 | 
				
			||||||
                            self.status = "failing"
 | 
					 | 
				
			||||||
                    else:
 | 
					 | 
				
			||||||
                        self.status = "failing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                if self.pass_if_svc_not_exist:
 | 
					 | 
				
			||||||
                    self.status = "passing"
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    self.status = "failing"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                self.more_info = f"Service {self.svc_name} does not exist"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.save(update_fields=["more_info"])
 | 
					            self.save(update_fields=["more_info"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.add_check_history(
 | 
					            self.add_check_history(
 | 
				
			||||||
@@ -488,49 +430,7 @@ class Check(BaseAuditModel):
 | 
				
			|||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        elif self.check_type == "eventlog":
 | 
					        elif self.check_type == "eventlog":
 | 
				
			||||||
            log = []
 | 
					            log = data["log"]
 | 
				
			||||||
            is_wildcard = self.event_id_is_wildcard
 | 
					 | 
				
			||||||
            eventType = self.event_type
 | 
					 | 
				
			||||||
            eventID = self.event_id
 | 
					 | 
				
			||||||
            source = self.event_source
 | 
					 | 
				
			||||||
            message = self.event_message
 | 
					 | 
				
			||||||
            r = data["log"]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            for i in r:
 | 
					 | 
				
			||||||
                if i["eventType"] == eventType:
 | 
					 | 
				
			||||||
                    if not is_wildcard and not int(i["eventID"]) == eventID:
 | 
					 | 
				
			||||||
                        continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if not source and not message:
 | 
					 | 
				
			||||||
                        if is_wildcard:
 | 
					 | 
				
			||||||
                            log.append(i)
 | 
					 | 
				
			||||||
                        elif int(i["eventID"]) == eventID:
 | 
					 | 
				
			||||||
                            log.append(i)
 | 
					 | 
				
			||||||
                        continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if source and message:
 | 
					 | 
				
			||||||
                        if is_wildcard:
 | 
					 | 
				
			||||||
                            if source in i["source"] and message in i["message"]:
 | 
					 | 
				
			||||||
                                log.append(i)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        elif int(i["eventID"]) == eventID:
 | 
					 | 
				
			||||||
                            if source in i["source"] and message in i["message"]:
 | 
					 | 
				
			||||||
                                log.append(i)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if source and source in i["source"]:
 | 
					 | 
				
			||||||
                        if is_wildcard:
 | 
					 | 
				
			||||||
                            log.append(i)
 | 
					 | 
				
			||||||
                        elif int(i["eventID"]) == eventID:
 | 
					 | 
				
			||||||
                            log.append(i)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if message and message in i["message"]:
 | 
					 | 
				
			||||||
                        if is_wildcard:
 | 
					 | 
				
			||||||
                            log.append(i)
 | 
					 | 
				
			||||||
                        elif int(i["eventID"]) == eventID:
 | 
					 | 
				
			||||||
                            log.append(i)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if self.fail_when == "contains":
 | 
					            if self.fail_when == "contains":
 | 
				
			||||||
                if log and len(log) >= self.number_of_events_b4_alert:
 | 
					                if log and len(log) >= self.number_of_events_b4_alert:
 | 
				
			||||||
                    self.status = "failing"
 | 
					                    self.status = "failing"
 | 
				
			||||||
@@ -567,6 +467,11 @@ class Check(BaseAuditModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return self.status
 | 
					        return self.status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def handle_assigned_task(self) -> None:
 | 
				
			||||||
 | 
					        for task in self.assignedtask.all():  # type: ignore
 | 
				
			||||||
 | 
					            if task.enabled:
 | 
				
			||||||
 | 
					                task.run_win_task()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def serialize(check):
 | 
					    def serialize(check):
 | 
				
			||||||
        # serializes the check and returns json
 | 
					        # serializes the check and returns json
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -158,14 +158,8 @@ class AssignedTaskCheckRunnerField(serializers.ModelSerializer):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class CheckRunnerGetSerializer(serializers.ModelSerializer):
 | 
					class CheckRunnerGetSerializer(serializers.ModelSerializer):
 | 
				
			||||||
    # only send data needed for agent to run a check
 | 
					    # only send data needed for agent to run a check
 | 
				
			||||||
    assigned_tasks = serializers.SerializerMethodField()
 | 
					 | 
				
			||||||
    script = ScriptCheckSerializer(read_only=True)
 | 
					    script = ScriptCheckSerializer(read_only=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_assigned_tasks(self, obj):
 | 
					 | 
				
			||||||
        if obj.assignedtask.exists():
 | 
					 | 
				
			||||||
            tasks = obj.assignedtask.all()
 | 
					 | 
				
			||||||
            return AssignedTaskCheckRunnerField(tasks, many=True).data
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = Check
 | 
					        model = Check
 | 
				
			||||||
        exclude = [
 | 
					        exclude = [
 | 
				
			||||||
@@ -193,6 +187,7 @@ class CheckRunnerGetSerializer(serializers.ModelSerializer):
 | 
				
			|||||||
            "modified_by",
 | 
					            "modified_by",
 | 
				
			||||||
            "modified_time",
 | 
					            "modified_time",
 | 
				
			||||||
            "history",
 | 
					            "history",
 | 
				
			||||||
 | 
					            "dashboard_alert",
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -400,7 +400,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        self.authenticate()
 | 
					        self.authenticate()
 | 
				
			||||||
        self.setup_coresettings()
 | 
					        self.setup_coresettings()
 | 
				
			||||||
        self.agent = baker.make_recipe("agents.agent")
 | 
					        self.agent = baker.make_recipe("agents.agent", version="1.5.7")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_prune_check_history(self):
 | 
					    def test_prune_check_history(self):
 | 
				
			||||||
        from .tasks import prune_check_history
 | 
					        from .tasks import prune_check_history
 | 
				
			||||||
@@ -526,6 +526,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
            "percent_used": 85,
 | 
					            "percent_used": 85,
 | 
				
			||||||
            "total": 500,
 | 
					            "total": 500,
 | 
				
			||||||
            "free": 400,
 | 
					            "free": 400,
 | 
				
			||||||
 | 
					            "more_info": "More info",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
@@ -543,6 +544,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
            "percent_used": 95,
 | 
					            "percent_used": 95,
 | 
				
			||||||
            "total": 500,
 | 
					            "total": 500,
 | 
				
			||||||
            "free": 400,
 | 
					            "free": 400,
 | 
				
			||||||
 | 
					            "more_info": "More info",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
@@ -573,6 +575,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
            "percent_used": 95,
 | 
					            "percent_used": 95,
 | 
				
			||||||
            "total": 500,
 | 
					            "total": 500,
 | 
				
			||||||
            "free": 400,
 | 
					            "free": 400,
 | 
				
			||||||
 | 
					            "more_info": "More info",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
@@ -592,6 +595,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
            "percent_used": 95,
 | 
					            "percent_used": 95,
 | 
				
			||||||
            "total": 500,
 | 
					            "total": 500,
 | 
				
			||||||
            "free": 400,
 | 
					            "free": 400,
 | 
				
			||||||
 | 
					            "more_info": "More info",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
@@ -608,6 +612,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
            "percent_used": 50,
 | 
					            "percent_used": 50,
 | 
				
			||||||
            "total": 500,
 | 
					            "total": 500,
 | 
				
			||||||
            "free": 400,
 | 
					            "free": 400,
 | 
				
			||||||
 | 
					            "more_info": "More info",
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
@@ -791,12 +796,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # test failing info
 | 
					        # test failing info
 | 
				
			||||||
        data = {
 | 
					        data = {"id": ping.id, "status": "failing", "output": "reply from a.com"}
 | 
				
			||||||
            "id": ping.id,
 | 
					 | 
				
			||||||
            "output": "Reply from 192.168.1.27: Destination host unreachable",
 | 
					 | 
				
			||||||
            "has_stdout": True,
 | 
					 | 
				
			||||||
            "has_stderr": False,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
        self.assertEqual(resp.status_code, 200)
 | 
					        self.assertEqual(resp.status_code, 200)
 | 
				
			||||||
@@ -806,13 +806,6 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        self.assertEqual(new_check.alert_severity, "info")
 | 
					        self.assertEqual(new_check.alert_severity, "info")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # test failing warning
 | 
					        # test failing warning
 | 
				
			||||||
        data = {
 | 
					 | 
				
			||||||
            "id": ping.id,
 | 
					 | 
				
			||||||
            "output": "Reply from 192.168.1.27: Destination host unreachable",
 | 
					 | 
				
			||||||
            "has_stdout": True,
 | 
					 | 
				
			||||||
            "has_stderr": False,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ping.alert_severity = "warning"
 | 
					        ping.alert_severity = "warning"
 | 
				
			||||||
        ping.save()
 | 
					        ping.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -824,13 +817,6 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        self.assertEqual(new_check.alert_severity, "warning")
 | 
					        self.assertEqual(new_check.alert_severity, "warning")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # test failing error
 | 
					        # test failing error
 | 
				
			||||||
        data = {
 | 
					 | 
				
			||||||
            "id": ping.id,
 | 
					 | 
				
			||||||
            "output": "Reply from 192.168.1.27: Destination host unreachable",
 | 
					 | 
				
			||||||
            "has_stdout": True,
 | 
					 | 
				
			||||||
            "has_stderr": False,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ping.alert_severity = "error"
 | 
					        ping.alert_severity = "error"
 | 
				
			||||||
        ping.save()
 | 
					        ping.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -842,13 +828,6 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        self.assertEqual(new_check.alert_severity, "error")
 | 
					        self.assertEqual(new_check.alert_severity, "error")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # test failing error
 | 
					        # test failing error
 | 
				
			||||||
        data = {
 | 
					 | 
				
			||||||
            "id": ping.id,
 | 
					 | 
				
			||||||
            "output": "some output",
 | 
					 | 
				
			||||||
            "has_stdout": False,
 | 
					 | 
				
			||||||
            "has_stderr": True,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
        self.assertEqual(resp.status_code, 200)
 | 
					        self.assertEqual(resp.status_code, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -857,12 +836,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        self.assertEqual(new_check.alert_severity, "error")
 | 
					        self.assertEqual(new_check.alert_severity, "error")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # test passing
 | 
					        # test passing
 | 
				
			||||||
        data = {
 | 
					        data = {"id": ping.id, "status": "passing", "output": "reply from a.com"}
 | 
				
			||||||
            "id": ping.id,
 | 
					 | 
				
			||||||
            "output": "Reply from 192.168.1.1: bytes=32 time<1ms TTL=64",
 | 
					 | 
				
			||||||
            "has_stdout": True,
 | 
					 | 
				
			||||||
            "has_stderr": False,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
        self.assertEqual(resp.status_code, 200)
 | 
					        self.assertEqual(resp.status_code, 200)
 | 
				
			||||||
@@ -881,7 +855,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # test passing running
 | 
					        # test passing running
 | 
				
			||||||
        data = {"id": winsvc.id, "exists": True, "status": "running"}
 | 
					        data = {"id": winsvc.id, "status": "passing", "more_info": "ok"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
        self.assertEqual(resp.status_code, 200)
 | 
					        self.assertEqual(resp.status_code, 200)
 | 
				
			||||||
@@ -889,20 +863,8 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        new_check = Check.objects.get(pk=winsvc.id)
 | 
					        new_check = Check.objects.get(pk=winsvc.id)
 | 
				
			||||||
        self.assertEqual(new_check.status, "passing")
 | 
					        self.assertEqual(new_check.status, "passing")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # test passing start pending
 | 
					        # test failing
 | 
				
			||||||
        winsvc.pass_if_start_pending = True
 | 
					        data = {"id": winsvc.id, "status": "failing", "more_info": "ok"}
 | 
				
			||||||
        winsvc.save()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        data = {"id": winsvc.id, "exists": True, "status": "start_pending"}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					 | 
				
			||||||
        self.assertEqual(resp.status_code, 200)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        new_check = Check.objects.get(pk=winsvc.id)
 | 
					 | 
				
			||||||
        self.assertEqual(new_check.status, "passing")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # test failing no start
 | 
					 | 
				
			||||||
        data = {"id": winsvc.id, "exists": True, "status": "not running"}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        resp = self.client.patch(url, data, format="json")
 | 
					        resp = self.client.patch(url, data, format="json")
 | 
				
			||||||
        self.assertEqual(resp.status_code, 200)
 | 
					        self.assertEqual(resp.status_code, 200)
 | 
				
			||||||
@@ -911,7 +873,7 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        self.assertEqual(new_check.status, "failing")
 | 
					        self.assertEqual(new_check.status, "failing")
 | 
				
			||||||
        self.assertEqual(new_check.alert_severity, "info")
 | 
					        self.assertEqual(new_check.alert_severity, "info")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # test failing and attempt start
 | 
					        """ # test failing and attempt start
 | 
				
			||||||
        winsvc.restart_if_stopped = True
 | 
					        winsvc.restart_if_stopped = True
 | 
				
			||||||
        winsvc.alert_severity = "warning"
 | 
					        winsvc.alert_severity = "warning"
 | 
				
			||||||
        winsvc.save()
 | 
					        winsvc.save()
 | 
				
			||||||
@@ -976,9 +938,9 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
        self.assertEqual(resp.status_code, 200)
 | 
					        self.assertEqual(resp.status_code, 200)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        new_check = Check.objects.get(pk=winsvc.id)
 | 
					        new_check = Check.objects.get(pk=winsvc.id)
 | 
				
			||||||
        self.assertEqual(new_check.status, "passing")
 | 
					        self.assertEqual(new_check.status, "passing") """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_handle_eventlog_check(self):
 | 
					    """ def test_handle_eventlog_check(self):
 | 
				
			||||||
        from checks.models import Check
 | 
					        from checks.models import Check
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        url = "/api/v3/checkrunner/"
 | 
					        url = "/api/v3/checkrunner/"
 | 
				
			||||||
@@ -1180,4 +1142,4 @@ class TestCheckTasks(TacticalTestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        new_check = Check.objects.get(pk=eventlog.id)
 | 
					        new_check = Check.objects.get(pk=eventlog.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertEquals(new_check.status, "passing")
 | 
					        self.assertEquals(new_check.status, "passing") """
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
from django.core.management.base import BaseCommand
 | 
					from django.core.management.base import BaseCommand
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from agents.models import Agent
 | 
					 | 
				
			||||||
from logs.models import PendingAction
 | 
					from logs.models import PendingAction
 | 
				
			||||||
from scripts.models import Script
 | 
					from scripts.models import Script
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9,22 +8,6 @@ class Command(BaseCommand):
 | 
				
			|||||||
    help = "Collection of tasks to run after updating the rmm, after migrations"
 | 
					    help = "Collection of tasks to run after updating the rmm, after migrations"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle(self, *args, **kwargs):
 | 
					    def handle(self, *args, **kwargs):
 | 
				
			||||||
        # 10-16-2020 changed the type of the agent's 'disks' model field
 | 
					 | 
				
			||||||
        # from a dict of dicts, to a list of disks in the golang agent
 | 
					 | 
				
			||||||
        # the following will convert dicts to lists for agent's still on the python agent
 | 
					 | 
				
			||||||
        agents = Agent.objects.only("pk", "disks")
 | 
					 | 
				
			||||||
        for agent in agents:
 | 
					 | 
				
			||||||
            if agent.disks is not None and isinstance(agent.disks, dict):
 | 
					 | 
				
			||||||
                new = []
 | 
					 | 
				
			||||||
                for k, v in agent.disks.items():
 | 
					 | 
				
			||||||
                    new.append(v)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                agent.disks = new
 | 
					 | 
				
			||||||
                agent.save(update_fields=["disks"])
 | 
					 | 
				
			||||||
                self.stdout.write(
 | 
					 | 
				
			||||||
                    self.style.SUCCESS(f"Migrated disks on {agent.hostname}")
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # remove task pending actions. deprecated 4/20/2021
 | 
					        # remove task pending actions. deprecated 4/20/2021
 | 
				
			||||||
        PendingAction.objects.filter(action_type="taskaction").delete()
 | 
					        PendingAction.objects.filter(action_type="taskaction").delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,7 +85,7 @@ def dashboard_info(request):
 | 
				
			|||||||
            "client_tree_sort": request.user.client_tree_sort,
 | 
					            "client_tree_sort": request.user.client_tree_sort,
 | 
				
			||||||
            "client_tree_splitter": request.user.client_tree_splitter,
 | 
					            "client_tree_splitter": request.user.client_tree_splitter,
 | 
				
			||||||
            "loading_bar_color": request.user.loading_bar_color,
 | 
					            "loading_bar_color": request.user.loading_bar_color,
 | 
				
			||||||
            "no_code_sign": hasattr(settings, "NOCODESIGN") and settings.NOCODESIGN,
 | 
					            "hosted": hasattr(settings, "HOSTED") and settings.HOSTED,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
asgiref==3.3.4
 | 
					asgiref==3.3.4
 | 
				
			||||||
asyncio-nats-client==0.11.4
 | 
					asyncio-nats-client==0.11.4
 | 
				
			||||||
celery==5.0.5
 | 
					celery==5.1.0
 | 
				
			||||||
certifi==2020.12.5
 | 
					certifi==2020.12.5
 | 
				
			||||||
cffi==1.14.5
 | 
					cffi==1.14.5
 | 
				
			||||||
channels==3.0.3
 | 
					channels==3.0.3
 | 
				
			||||||
@@ -8,12 +8,11 @@ channels_redis==3.2.0
 | 
				
			|||||||
chardet==4.0.0
 | 
					chardet==4.0.0
 | 
				
			||||||
cryptography==3.4.7
 | 
					cryptography==3.4.7
 | 
				
			||||||
daphne==3.0.2
 | 
					daphne==3.0.2
 | 
				
			||||||
Django==3.2.2
 | 
					Django==3.2.3
 | 
				
			||||||
django-cors-headers==3.7.0
 | 
					django-cors-headers==3.7.0
 | 
				
			||||||
django-rest-knox==4.1.0
 | 
					django-rest-knox==4.1.0
 | 
				
			||||||
djangorestframework==3.12.4
 | 
					djangorestframework==3.12.4
 | 
				
			||||||
future==0.18.2
 | 
					future==0.18.2
 | 
				
			||||||
kombu==5.0.2
 | 
					 | 
				
			||||||
loguru==0.5.3
 | 
					loguru==0.5.3
 | 
				
			||||||
msgpack==1.0.2
 | 
					msgpack==1.0.2
 | 
				
			||||||
packaging==20.9
 | 
					packaging==20.9
 | 
				
			||||||
@@ -26,10 +25,10 @@ pytz==2021.1
 | 
				
			|||||||
qrcode==6.1
 | 
					qrcode==6.1
 | 
				
			||||||
redis==3.5.3
 | 
					redis==3.5.3
 | 
				
			||||||
requests==2.25.1
 | 
					requests==2.25.1
 | 
				
			||||||
six==1.15.0
 | 
					six==1.16.0
 | 
				
			||||||
sqlparse==0.4.1
 | 
					sqlparse==0.4.1
 | 
				
			||||||
twilio==6.57.0
 | 
					twilio==6.59.0
 | 
				
			||||||
urllib3==1.26.4
 | 
					urllib3==1.26.5
 | 
				
			||||||
uWSGI==2.0.19.1
 | 
					uWSGI==2.0.19.1
 | 
				
			||||||
validators==0.18.2
 | 
					validators==0.18.2
 | 
				
			||||||
vine==5.0.0
 | 
					vine==5.0.0
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,9 @@
 | 
				
			|||||||
    "name": "Firefox - Clean Cache",
 | 
					    "name": "Firefox - Clean Cache",
 | 
				
			||||||
    "description": "This script will clean up Mozilla Firefox for all users.",
 | 
					    "description": "This script will clean up Mozilla Firefox for all users.",
 | 
				
			||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):Browsers"
 | 
					    "category": "TRMM (Win):Browsers",
 | 
				
			||||||
 | 
					    "default_timeout": "300"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "3ff6a386-11d1-4f9d-8cca-1b0563bb6443",
 | 
					    "guid": "3ff6a386-11d1-4f9d-8cca-1b0563bb6443",
 | 
				
			||||||
@@ -15,7 +17,8 @@
 | 
				
			|||||||
    "name": "Chrome - Clear Cache for All Users",
 | 
					    "name": "Chrome - Clear Cache for All Users",
 | 
				
			||||||
    "description": "This script will clean up Google Chrome for all users.",
 | 
					    "description": "This script will clean up Google Chrome for all users.",
 | 
				
			||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):Browsers"
 | 
					    "category": "TRMM (Win):Browsers",
 | 
				
			||||||
 | 
					    "default_timeout": "300"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "be1de837-f677-4ac5-aa0c-37a0fc9991fc",
 | 
					    "guid": "be1de837-f677-4ac5-aa0c-37a0fc9991fc",
 | 
				
			||||||
@@ -24,7 +27,8 @@
 | 
				
			|||||||
    "name": "Adobe Reader DC - Install",
 | 
					    "name": "Adobe Reader DC - Install",
 | 
				
			||||||
    "description": "Installs Adobe Reader DC.",
 | 
					    "description": "Installs Adobe Reader DC.",
 | 
				
			||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):3rd Party Software>Chocolatey"
 | 
					    "category": "TRMM (Win):3rd Party Software>Chocolatey",
 | 
				
			||||||
 | 
					    "default_timeout": "300"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "2ee134d5-76aa-4160-b334-a1efbc62079f",
 | 
					    "guid": "2ee134d5-76aa-4160-b334-a1efbc62079f",
 | 
				
			||||||
@@ -33,7 +37,8 @@
 | 
				
			|||||||
    "name": "Duplicati - Install",
 | 
					    "name": "Duplicati - Install",
 | 
				
			||||||
    "description": "This script installs Duplicati 2.0.5.1 as a service.",
 | 
					    "description": "This script installs Duplicati 2.0.5.1 as a service.",
 | 
				
			||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):3rd Party Software"
 | 
					    "category": "TRMM (Win):3rd Party Software",
 | 
				
			||||||
 | 
					    "default_timeout": "300"   
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "81cc5bcb-01bf-4b0c-89b9-0ac0f3fe0c04",
 | 
					    "guid": "81cc5bcb-01bf-4b0c-89b9-0ac0f3fe0c04",
 | 
				
			||||||
@@ -42,7 +47,8 @@
 | 
				
			|||||||
    "name": "Windows Update - Reset",
 | 
					    "name": "Windows Update - Reset",
 | 
				
			||||||
    "description": "This script will reset all of the Windows Updates components to DEFAULT SETTINGS.",
 | 
					    "description": "This script will reset all of the Windows Updates components to DEFAULT SETTINGS.",
 | 
				
			||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):Updates"
 | 
					    "category": "TRMM (Win):Updates",
 | 
				
			||||||
 | 
					    "default_timeout": "300"    
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "8db87ff0-a9b4-4d9d-bc55-377bbcb85b6d",
 | 
					    "guid": "8db87ff0-a9b4-4d9d-bc55-377bbcb85b6d",
 | 
				
			||||||
@@ -51,7 +57,8 @@
 | 
				
			|||||||
    "name": "Disk - Cleanup C: drive",
 | 
					    "name": "Disk - Cleanup C: drive",
 | 
				
			||||||
    "description": "Cleans the C: drive's Window Temperary files, Windows SoftwareDistribution folder, the local users Temperary folder, IIS logs (if applicable) and empties the recycling bin. All deleted files will go into a log transcript in $env:TEMP. By default this script leaves files that are newer than 7 days old however this variable can be edited.",
 | 
					    "description": "Cleans the C: drive's Window Temperary files, Windows SoftwareDistribution folder, the local users Temperary folder, IIS logs (if applicable) and empties the recycling bin. All deleted files will go into a log transcript in $env:TEMP. By default this script leaves files that are newer than 7 days old however this variable can be edited.",
 | 
				
			||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):Maintenance"
 | 
					    "category": "TRMM (Win):Maintenance",
 | 
				
			||||||
 | 
					    "default_timeout": "25000"    
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "2f28e8c1-ae0f-4b46-a826-f513974526a3",
 | 
					    "guid": "2f28e8c1-ae0f-4b46-a826-f513974526a3",
 | 
				
			||||||
@@ -78,7 +85,8 @@
 | 
				
			|||||||
    "name": "Speed Test - Python",
 | 
					    "name": "Speed Test - Python",
 | 
				
			||||||
    "description": "Runs a Speed Test using Python",
 | 
					    "description": "Runs a Speed Test using Python",
 | 
				
			||||||
    "shell": "python",
 | 
					    "shell": "python",
 | 
				
			||||||
    "category": "TRMM (Win):Network"
 | 
					    "category": "TRMM (Win):Network",
 | 
				
			||||||
 | 
					    "default_timeout": "120"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "9d34f482-1f0c-4b2f-b65f-a9cf3c13ef5f",
 | 
					    "guid": "9d34f482-1f0c-4b2f-b65f-a9cf3c13ef5f",
 | 
				
			||||||
@@ -161,6 +169,18 @@
 | 
				
			|||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):Collectors"
 | 
					    "category": "TRMM (Win):Collectors"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "guid": "973c34d7-cab0-4fda-999c-b4933655f946",
 | 
				
			||||||
 | 
					    "filename": "Win_Screenconnect_GetGUID.ps1",
 | 
				
			||||||
 | 
					    "submittedBy": "https://github.com/silversword411",
 | 
				
			||||||
 | 
					    "name": "Screenconnect - Get GUID for client",
 | 
				
			||||||
 | 
					    "description": "Returns Screenconnect GUID for client - Use with Custom Fields for later use. ",
 | 
				
			||||||
 | 
					    "args": [
 | 
				
			||||||
 | 
					      "-serviceName {{client.ScreenConnectService}}"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "shell": "powershell",
 | 
				
			||||||
 | 
					    "category": "TRMM (Win):Collectors"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "95a2ee6f-b89b-4551-856e-3081b041caa7",
 | 
					    "guid": "95a2ee6f-b89b-4551-856e-3081b041caa7",
 | 
				
			||||||
    "filename": "Win_Power_Profile_Reset_High_Performance_to_Defaults.ps1",
 | 
					    "filename": "Win_Power_Profile_Reset_High_Performance_to_Defaults.ps1",
 | 
				
			||||||
@@ -186,7 +206,8 @@
 | 
				
			|||||||
    "name": "Windows 10 Upgrade",
 | 
					    "name": "Windows 10 Upgrade",
 | 
				
			||||||
    "description": "Forces an upgrade to the latest release of Windows 10.",
 | 
					    "description": "Forces an upgrade to the latest release of Windows 10.",
 | 
				
			||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):Updates"
 | 
					    "category": "TRMM (Win):Updates",
 | 
				
			||||||
 | 
					    "default_timeout": "25000"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "375323e5-cac6-4f35-a304-bb7cef35902d",
 | 
					    "guid": "375323e5-cac6-4f35-a304-bb7cef35902d",
 | 
				
			||||||
@@ -222,7 +243,8 @@
 | 
				
			|||||||
    "name": "SSH - Install Feature and Enable",
 | 
					    "name": "SSH - Install Feature and Enable",
 | 
				
			||||||
    "description": "Installs and enabled OpenSSH Server Feature in Win10",
 | 
					    "description": "Installs and enabled OpenSSH Server Feature in Win10",
 | 
				
			||||||
    "shell": "powershell",
 | 
					    "shell": "powershell",
 | 
				
			||||||
    "category": "TRMM (Win):Windows Features"
 | 
					    "category": "TRMM (Win):Windows Features",
 | 
				
			||||||
 | 
					    "default_timeout": "300"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "2435297a-6263-4e90-8688-1847400d0e22",
 | 
					    "guid": "2435297a-6263-4e90-8688-1847400d0e22",
 | 
				
			||||||
@@ -339,7 +361,8 @@
 | 
				
			|||||||
    "name": "Update Installed Apps",
 | 
					    "name": "Update Installed Apps",
 | 
				
			||||||
    "description": "Update all apps that were installed using Chocolatey.",
 | 
					    "description": "Update all apps that were installed using Chocolatey.",
 | 
				
			||||||
    "shell": "cmd",
 | 
					    "shell": "cmd",
 | 
				
			||||||
    "category": "TRMM (Win):3rd Party Software>Chocolatey"
 | 
					    "category": "TRMM (Win):3rd Party Software>Chocolatey",
 | 
				
			||||||
 | 
					    "default_timeout": "3600"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    "guid": "fff8024d-d72e-4457-84fa-6c780f69a16f",
 | 
					    "guid": "fff8024d-d72e-4457-84fa-6c780f69a16f",
 | 
				
			||||||
@@ -660,4 +683,4 @@
 | 
				
			|||||||
    "category": "TRMM (Win):Misc>Reference",
 | 
					    "category": "TRMM (Win):Misc>Reference",
 | 
				
			||||||
    "default_timeout": "1"
 | 
					    "default_timeout": "1"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ app.conf.beat_schedule = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    "get-wmi": {
 | 
					    "get-wmi": {
 | 
				
			||||||
        "task": "agents.tasks.get_wmi_task",
 | 
					        "task": "agents.tasks.get_wmi_task",
 | 
				
			||||||
        "schedule": crontab(minute="*/18"),
 | 
					        "schedule": crontab(minute=18, hour="*/5"),
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,22 +15,22 @@ EXE_DIR = os.path.join(BASE_DIR, "tacticalrmm/private/exe")
 | 
				
			|||||||
AUTH_USER_MODEL = "accounts.User"
 | 
					AUTH_USER_MODEL = "accounts.User"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# latest release
 | 
					# latest release
 | 
				
			||||||
TRMM_VERSION = "0.6.10"
 | 
					TRMM_VERSION = "0.6.13"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# bump this version everytime vue code is changed
 | 
					# bump this version everytime vue code is changed
 | 
				
			||||||
# to alert user they need to manually refresh their browser
 | 
					# to alert user they need to manually refresh their browser
 | 
				
			||||||
APP_VER = "0.0.136"
 | 
					APP_VER = "0.0.137"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# https://github.com/wh1te909/rmmagent
 | 
					# https://github.com/wh1te909/rmmagent
 | 
				
			||||||
LATEST_AGENT_VER = "1.5.6"
 | 
					LATEST_AGENT_VER = "1.5.7"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MESH_VER = "0.8.35"
 | 
					MESH_VER = "0.8.49"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# for the update script, bump when need to recreate venv or npm install
 | 
					# for the update script, bump when need to recreate venv or npm install
 | 
				
			||||||
PIP_VER = "16"
 | 
					PIP_VER = "17"
 | 
				
			||||||
NPM_VER = "15"
 | 
					NPM_VER = "16"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SETUPTOOLS_VER = "56.1.0"
 | 
					SETUPTOOLS_VER = "57.0.0"
 | 
				
			||||||
WHEEL_VER = "0.36.2"
 | 
					WHEEL_VER = "0.36.2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DL_64 = f"https://github.com/wh1te909/rmmagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}.exe"
 | 
					DL_64 = f"https://github.com/wh1te909/rmmagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}.exe"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
FROM nats:2.2-alpine
 | 
					FROM nats:2.2.6-alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENV TACTICAL_DIR /opt/tactical
 | 
					ENV TACTICAL_DIR /opt/tactical
 | 
				
			||||||
ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready
 | 
					ENV TACTICAL_READY_FILE ${TACTICAL_DIR}/tmp/tactical.ready
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								docs/docs/functions/examples.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								docs/docs/functions/examples.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					# Examples
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Create Run URL Action to Computer support page
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This will create a URL link that will take you to the support page for a computer based on the computers Serial Number
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Goto `Settings | Global Settings | Custom Fields` 
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Under Agents tab Add Custom Field (CaSe SeNsItIve)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Create Task (best to use `Settings | Automation Manager` if you want to apply it to all computers). Add script that has an output of the data you want.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Create URL Action (under `Settings | Global Settings | URL ACTIONS`) for Manufacturer websites
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Dell Support Page
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					https://www.dell.com/support/home/en-us/product-support/servicetag/{{agent.SerialNumber}}/overview
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Lenovo  Support Page
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					https://www.dell.com/support/home/en-us/product-support/servicetag/{{agent.SerialNumber}}/overview
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
							
								
								
									
										19
									
								
								docs/docs/functions/settings_override.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								docs/docs/functions/settings_override.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					# Settings Override
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Browser token expiration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The default browser token expiration is set to 5 hours. See this [ticket](https://github.com/wh1te909/tacticalrmm/issues/503) for reference.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To change it, add the following code block to the end of `/rmm/api/tacticalrmm/tacticalrmm/local_settings.py`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					from datetime import timedelta
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REST_KNOX = {
 | 
				
			||||||
 | 
					    "TOKEN_TTL": timedelta(days=30),
 | 
				
			||||||
 | 
					    "AUTO_REFRESH": True,
 | 
				
			||||||
 | 
					    "MIN_REFRESH_INTERVAL": 600,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Change `(days=30)` to whatever you prefer. Then run `sudo systemctl restart rmm` for changes to take effect.
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								docs/docs/images/example1_customfield.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/docs/images/example1_customfield.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 13 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/docs/images/example1_taskcollectorscript.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/docs/images/example1_taskcollectorscript.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 24 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								docs/docs/images/example1_urlaction.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/docs/images/example1_urlaction.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 16 KiB  | 
@@ -14,6 +14,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Install
 | 
					## Install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					!!!info
 | 
				
			||||||
 | 
					    It is recommended that you keep your server updated regularly (monthly). SSL wildcard certs will expire every 3 months and need manual updating as well. <br/><br/>
 | 
				
			||||||
 | 
					    Until we reach production release, there may be architectural changes that may be made to Tactical RMM and only a regular patching schedule is supported by developers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### Run updates and setup the linux user
 | 
					#### Run updates and setup the linux user
 | 
				
			||||||
SSH into the server as **root**.<br/><br/>
 | 
					SSH into the server as **root**.<br/><br/>
 | 
				
			||||||
Download and run the prereqs and latest updates<br/>
 | 
					Download and run the prereqs and latest updates<br/>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,8 @@ nav:
 | 
				
			|||||||
      - "Alerting": functions/alerting.md
 | 
					      - "Alerting": functions/alerting.md
 | 
				
			||||||
      - "User Interface Preferences": functions/user_ui.md
 | 
					      - "User Interface Preferences": functions/user_ui.md
 | 
				
			||||||
      - "Django Admin": functions/django_admin.md
 | 
					      - "Django Admin": functions/django_admin.md
 | 
				
			||||||
 | 
					      - "Settings Override": functions/settings_override.md
 | 
				
			||||||
 | 
					      - "Examples": functions/examples.md
 | 
				
			||||||
  - Backup: backup.md
 | 
					  - Backup: backup.md
 | 
				
			||||||
  - Restore: restore.md
 | 
					  - Restore: restore.md
 | 
				
			||||||
  - Troubleshooting: troubleshooting.md
 | 
					  - Troubleshooting: troubleshooting.md
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@@ -5,6 +5,6 @@ go 1.16
 | 
				
			|||||||
require (
 | 
					require (
 | 
				
			||||||
	github.com/nats-io/nats-server/v2 v2.1.8-0.20201129161730-ebe63db3e3ed // indirect
 | 
						github.com/nats-io/nats-server/v2 v2.1.8-0.20201129161730-ebe63db3e3ed // indirect
 | 
				
			||||||
	github.com/nats-io/nats.go v1.11.0
 | 
						github.com/nats-io/nats.go v1.11.0
 | 
				
			||||||
	github.com/ugorji/go/codec v1.2.5
 | 
						github.com/ugorji/go/codec v1.2.6
 | 
				
			||||||
	golang.org/x/sys v0.0.0-20210122235752-a8b976e07c7b // indirect
 | 
						golang.org/x/sys v0.0.0-20210122235752-a8b976e07c7b // indirect
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							@@ -34,10 +34,10 @@ github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
 | 
				
			|||||||
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
 | 
					github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
 | 
				
			||||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
 | 
					github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
 | 
				
			||||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
 | 
					github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
 | 
				
			||||||
github.com/ugorji/go v1.2.5 h1:NozRHfUeEta89taVkyfsDVSy2f7v89Frft4pjnWuGuc=
 | 
					github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
 | 
				
			||||||
github.com/ugorji/go v1.2.5/go.mod h1:gat2tIT8KJG8TVI8yv77nEO/KYT6dV7JE1gfUa8Xuls=
 | 
					github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
 | 
				
			||||||
github.com/ugorji/go/codec v1.2.5 h1:8WobZKAk18Msm2CothY2jnztY56YVY8kF1oQrj21iis=
 | 
					github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
 | 
				
			||||||
github.com/ugorji/go/codec v1.2.5/go.mod h1:QPxoTbPKSEAlAHPYt02++xp/en9B/wUdwFCz+hj5caA=
 | 
					github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
					golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
					golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
					golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SCRIPT_VERSION="48"
 | 
					SCRIPT_VERSION="49"
 | 
				
			||||||
SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/install.sh'
 | 
					SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/install.sh'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sudo apt install -y curl wget dirmngr gnupg lsb-release
 | 
					sudo apt install -y curl wget dirmngr gnupg lsb-release
 | 
				
			||||||
@@ -167,11 +167,11 @@ sudo chmod 775 -R /etc/letsencrypt
 | 
				
			|||||||
print_green 'Downloading NATS'
 | 
					print_green 'Downloading NATS'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
 | 
					nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
 | 
				
			||||||
wget https://github.com/nats-io/nats-server/releases/download/v2.2.3/nats-server-v2.2.3-linux-amd64.tar.gz -P ${nats_tmp}
 | 
					wget https://github.com/nats-io/nats-server/releases/download/v2.2.6/nats-server-v2.2.6-linux-amd64.tar.gz -P ${nats_tmp}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tar -xzf ${nats_tmp}/nats-server-v2.2.3-linux-amd64.tar.gz -C ${nats_tmp}
 | 
					tar -xzf ${nats_tmp}/nats-server-v2.2.6-linux-amd64.tar.gz -C ${nats_tmp}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sudo mv ${nats_tmp}/nats-server-v2.2.3-linux-amd64/nats-server /usr/local/bin/
 | 
					sudo mv ${nats_tmp}/nats-server-v2.2.6-linux-amd64/nats-server /usr/local/bin/
 | 
				
			||||||
sudo chmod +x /usr/local/bin/nats-server
 | 
					sudo chmod +x /usr/local/bin/nats-server
 | 
				
			||||||
sudo chown ${USER}:${USER} /usr/local/bin/nats-server
 | 
					sudo chown ${USER}:${USER} /usr/local/bin/nats-server
 | 
				
			||||||
rm -rf ${nats_tmp}
 | 
					rm -rf ${nats_tmp}
 | 
				
			||||||
 
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SCRIPT_VERSION="26"
 | 
					SCRIPT_VERSION="27"
 | 
				
			||||||
SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/restore.sh'
 | 
					SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/restore.sh'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sudo apt update
 | 
					sudo apt update
 | 
				
			||||||
@@ -108,11 +108,11 @@ sudo apt update
 | 
				
			|||||||
print_green 'Downloading NATS'
 | 
					print_green 'Downloading NATS'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
 | 
					nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
 | 
				
			||||||
wget https://github.com/nats-io/nats-server/releases/download/v2.2.3/nats-server-v2.2.3-linux-amd64.tar.gz -P ${nats_tmp}
 | 
					wget https://github.com/nats-io/nats-server/releases/download/v2.2.6/nats-server-v2.2.6-linux-amd64.tar.gz -P ${nats_tmp}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tar -xzf ${nats_tmp}/nats-server-v2.2.3-linux-amd64.tar.gz -C ${nats_tmp}
 | 
					tar -xzf ${nats_tmp}/nats-server-v2.2.6-linux-amd64.tar.gz -C ${nats_tmp}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sudo mv ${nats_tmp}/nats-server-v2.2.3-linux-amd64/nats-server /usr/local/bin/
 | 
					sudo mv ${nats_tmp}/nats-server-v2.2.6-linux-amd64/nats-server /usr/local/bin/
 | 
				
			||||||
sudo chmod +x /usr/local/bin/nats-server
 | 
					sudo chmod +x /usr/local/bin/nats-server
 | 
				
			||||||
sudo chown ${USER}:${USER} /usr/local/bin/nats-server
 | 
					sudo chown ${USER}:${USER} /usr/local/bin/nats-server
 | 
				
			||||||
rm -rf ${nats_tmp}
 | 
					rm -rf ${nats_tmp}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
cup -y all
 | 
					cup all -y
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,6 +31,7 @@ else {
 | 
				
			|||||||
    Install-Module -Name RunAsUser -Force
 | 
					    Install-Module -Name RunAsUser -Force
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Used to pull variables in and use them inside the script block. Contains message to show user
 | 
				
			||||||
Set-Content -Path c:\windows\temp\message.txt -Value $args
 | 
					Set-Content -Path c:\windows\temp\message.txt -Value $args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Invoke-AsCurrentUser -scriptblock {
 | 
					Invoke-AsCurrentUser -scriptblock {
 | 
				
			||||||
@@ -55,5 +56,5 @@ Invoke-AsCurrentUser -scriptblock {
 | 
				
			|||||||
    Submit-BTNotification -Content $Content
 | 
					    Submit-BTNotification -Content $Content
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Cleanup temp file for message variables
 | 
				
			||||||
Remove-Item -Path c:\windows\temp\message.txt
 | 
					Remove-Item -Path c:\windows\temp\message.txt
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,28 +10,6 @@
 | 
				
			|||||||
   Submitted by: https://github.com/dinger1986
 | 
					   Submitted by: https://github.com/dinger1986
 | 
				
			||||||
#>
 | 
					#>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$regpath = HKCU:\Software\Microsoft\Office\16.0\Outlook\Preferences
 | 
					 | 
				
			||||||
$regname = DelegateSentItemsStyle
 | 
					 | 
				
			||||||
$regvalue = 1
 | 
					 | 
				
			||||||
$regproperty = Dword
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If (!(test-path '%ProgramData%\Tactical RMM\temp')) {
 | 
					 | 
				
			||||||
    New-Item -ItemType Directory -Force -Path '%ProgramData%\Tactical RMM\temp'
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
If (!(test-path C:\TEMP\curpsxpolicy.txt)) {
 | 
					 | 
				
			||||||
    $curexpolicy = Get-ExecutionPolicy
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (
 | 
					 | 
				
			||||||
        echo $curexpolicy
 | 
					 | 
				
			||||||
    )>"%ProgramData%\Tactical RMM\temp\curpsxpolicy.txt"
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (Get-PackageProvider -Name NuGet) {
 | 
					if (Get-PackageProvider -Name NuGet) {
 | 
				
			||||||
    Write-Output "NuGet Already Added"
 | 
					    Write-Output "NuGet Already Added"
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
@@ -48,14 +26,30 @@ else {
 | 
				
			|||||||
    Install-Module -Name RunAsUser -Force
 | 
					    Install-Module -Name RunAsUser -Force
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If (!(test-path $env:programdata\TacticalRMM\temp\)) {
 | 
				
			||||||
 | 
					    New-Item -ItemType Directory -Force -Path $env:programdata\TacticalRMM\temp\
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If (!(test-path $env:programdata\TacticalRMM\temp\curpsxpolicy.txt)) {
 | 
				
			||||||
 | 
					    $curexpolicy = Get-ExecutionPolicy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					        Write-Output $curexpolicy
 | 
				
			||||||
 | 
					    )>$env:programdata\TacticalRMM\temp\curpsxpolicy.txt
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					Set-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell -Name ExecutionPolicy -Value Unrestricted
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Invoke-AsCurrentUser -scriptblock {
 | 
					Invoke-AsCurrentUser -scriptblock {
 | 
				
			||||||
    New-ItemProperty -Path "$regpath" -Name "$regname" -Value "$regvalue"  -PropertyType "$regproperty"
 | 
					    # Modify below for other versions of Office
 | 
				
			||||||
 | 
					    $regpath = 'Software\Microsoft\Office\16.0\Outlook\Preferences'
 | 
				
			||||||
 | 
					    $regname = "DelegateSentItemsStyle"
 | 
				
			||||||
 | 
					    $regvalue = "1"
 | 
				
			||||||
 | 
					    $regproperty = "Dword"
 | 
				
			||||||
 | 
					    New-ItemProperty -Path HKCU:\$regpath -Name $regname -Value $regvalue  -PropertyType $regproperty
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Write-Output "Successfully changed Sent Items for Delegated folders"
 | 
					Write-Output "Successfully changed Sent Items for Delegated folders"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$curpsxpol = Get-Content -Path "%ProgramData%\Tactical RMM\temp\curpsxpolicy.txt";
 | 
					$curpsxpol = Get-Content -Path $env:programdata\TacticalRMM\temp\curpsxpolicy.txt;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
Set-ExecutionPolicy -ExecutionPolicy $curpsxpol
 | 
					Set-ExecutionPolicy -ExecutionPolicy $curpsxpol
 | 
				
			||||||
 | 
					 | 
				
			||||||
del "%ProgramData%\Tactical RMM\temp\curpsxpolicy.txt"
 | 
					 | 
				
			||||||
							
								
								
									
										26
									
								
								scripts/Win_Screenconnect_GetGUID.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								scripts/Win_Screenconnect_GetGUID.ps1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					<#
 | 
				
			||||||
 | 
					Requires global variables for serviceName "ScreenConnectService" 
 | 
				
			||||||
 | 
					serviceName is the name of the ScreenConnect Service once it is installed EG: "ScreenConnect Client (1327465grctq84yrtocq)"
 | 
				
			||||||
 | 
					Variable value must start and end with " (Prior to TRMM Version 0.6.5), remove / don't use " on TRMM Version 0.6.5 or later.
 | 
				
			||||||
 | 
					Requires Custom Fields Agent entry Name: ScreenConnectGUID   Type: text
 | 
				
			||||||
 | 
					URL Action entry (check your screenconnect to see what folder name is your "All Machines" folder): https://YOURNAME.screenconnect.com/Host#Access/All%20Machines//{{agent.ScreenConnectGUID}}/Join
 | 
				
			||||||
 | 
					    or https://YOURNAME.screenconnect.com/Host#Access/All%20Machines%20by%20Company//{{agent.ScreenConnectGUID}}/Join
 | 
				
			||||||
 | 
					#>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					param (
 | 
				
			||||||
 | 
					    [string] $serviceName
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!$serviceName) {
 | 
				
			||||||
 | 
					    write-output "Variable not specified ScreenConnectService, please create a global custom field under Client called ScreenConnectService, Example Value: `"ScreenConnect Client (1327465grctq84yrtocq)`" `n"
 | 
				
			||||||
 | 
					    $ErrorCount += 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (!$ErrorCount -eq 0) {
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					$imagePath = Get-Itempropertyvalue "HKLM:\SYSTEM\ControlSet001\Services\$serviceName" -Name "ImagePath"
 | 
				
			||||||
 | 
					$imagePath2 = ($imagePath -split "&s=")[1]
 | 
				
			||||||
 | 
					$machineGUID = ($imagePath2 -split "&k=")[0]
 | 
				
			||||||
 | 
					Write-Output $machineGUID
 | 
				
			||||||
							
								
								
									
										18
									
								
								scripts_wip/Win_Print_Spooler_Reset.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								scripts_wip/Win_Print_Spooler_Reset.bat
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					REM Print Spooler reset script. Will stop spooler, fix permissions on print folders, clear all files in print queues, and restart spooler service.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Stop Print Spooler 
 | 
				
			||||||
 | 
					net stop "Spooler"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Kill service if its not stopping 
 | 
				
			||||||
 | 
					tasklist | find /i "spoolsv.exe" && taskkill /im spoolsv.exe /F && net stop "Spooler"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Set Permissions on spool folders
 | 
				
			||||||
 | 
					icacls %systemroot%\System32\spool\PRINTERS /grant system:f /inheritance:e
 | 
				
			||||||
 | 
					icacls %systemroot%\System32\spool\SERVERS /grant system:f /inheritance:e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Clear files in print queue
 | 
				
			||||||
 | 
					del /F /Q %systemroot%\System32\spool\PRINTERS\*.*
 | 
				
			||||||
 | 
					del /F /Q %systemroot%\System32\spool\SERVERS\*.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Start Print Spooler again
 | 
				
			||||||
 | 
					net start "Spooler"
 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
net stop "Print Spooler"
 | 
					 | 
				
			||||||
net start "Print Spooler"
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								scripts_wip/Win_Print_Spooler_Restart_Service.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								scripts_wip/Win_Print_Spooler_Restart_Service.ps1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					<#
 | 
				
			||||||
 | 
					.Synopsis
 | 
				
			||||||
 | 
					   Restart Print Spooler Service
 | 
				
			||||||
 | 
					.DESCRIPTION
 | 
				
			||||||
 | 
					   Will force-restart the spooler service. With additional command parameter will also delete any pending print jobs
 | 
				
			||||||
 | 
					.EXAMPLE
 | 
				
			||||||
 | 
					   Another example of how to use this cmdlet
 | 
				
			||||||
 | 
					.OUTPUTS
 | 
				
			||||||
 | 
					   Any print jobs that are deleted
 | 
				
			||||||
 | 
					.NOTES
 | 
				
			||||||
 | 
					   v1.0 5/2021
 | 
				
			||||||
 | 
					   https://github.com/silversword411
 | 
				
			||||||
 | 
					.FUNCTIONALITY
 | 
				
			||||||
 | 
					   Print Spooler Troubleshooting, restarts spooler service. Can also delete all print jobs that are pending 
 | 
				
			||||||
 | 
					#>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Restart Spooler service
 | 
				
			||||||
 | 
					Restart-Service -Name spooler -Force 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#Deletes All print jobs within the last 15 years
 | 
				
			||||||
 | 
					$PrintJobs = get-wmiobject -class "Win32_PrintJob" -namespace "root\CIMV2" -computername . | Where-Object { [System.Management.ManagementDateTimeConverter]::ToDateTime($_.TimeSubmitted) -lt (Get-Date).AddDays(-5500) } 
 | 
				
			||||||
 | 
					foreach ($job in $PrintJobs) {    
 | 
				
			||||||
 | 
					    #   Write-Host "Canceling job $($job.JobId)"    
 | 
				
			||||||
 | 
					    $job.Delete() 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
#Update with command parameters
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$PrintJobs = get-wmiobject -class "Win32_PrintJob" -namespace "root\CIMV2" -computername . | Where-Object {[System.Management.ManagementDateTimeConverter]::ToDateTime($_.TimeSubmitted) -lt (Get-Date).AddDays(-2)} 
 | 
					 | 
				
			||||||
foreach ($job in $PrintJobs) 
 | 
					 | 
				
			||||||
{    
 | 
					 | 
				
			||||||
#   Write-Host "Canceling job $($job.JobId)"    
 | 
					 | 
				
			||||||
    $job.Delete() 
 | 
					 | 
				
			||||||
} 
 | 
					 | 
				
			||||||
							
								
								
									
										18
									
								
								scripts_wip/Win_Shortcut_Creator.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								scripts_wip/Win_Shortcut_Creator.ps1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mkdir -Path 'C:\agent' -Force
 | 
				
			||||||
 | 
					Invoke-WebRequest "http://www.yourwebsite.com/logos/yourico.ico" -outfile "c:\agent\yourico.ico"
 | 
				
			||||||
 | 
					$WshShell = New-Object -comObject WScript.Shell
 | 
				
			||||||
 | 
					$path = "C:\Users\All Users\desktop\Shortcut.url"
 | 
				
			||||||
 | 
					$targetpath = "https://yourwebsite.com"
 | 
				
			||||||
 | 
					$iconlocation = "c:\agent\yourico.ico"
 | 
				
			||||||
 | 
					$iconfile = "IconFile=" + $iconlocation
 | 
				
			||||||
 | 
					$Shortcut = $WshShell.CreateShortcut($path)
 | 
				
			||||||
 | 
					$Shortcut.TargetPath = $targetpath
 | 
				
			||||||
 | 
					$Shortcut.Save()
 | 
				
			||||||
 | 
					Add-Content $path "HotKey=0"
 | 
				
			||||||
 | 
					Add-Content $path "$iconfile"
 | 
				
			||||||
 | 
					Add-Content $path "IconIndex=0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This will create and agent directory then download the ico file 
 | 
				
			||||||
 | 
					# change ico file and location to download
 | 
				
			||||||
							
								
								
									
										14
									
								
								scripts_wip/Win_Shortcut_Creator2.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								scripts_wip/Win_Shortcut_Creator2.ps1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					param (
 | 
				
			||||||
 | 
					  [string] $name,
 | 
				
			||||||
 | 
					  [string] $url
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$url = $url
 | 
				
			||||||
 | 
					$name = $name
 | 
				
			||||||
 | 
					$Shell = New-Object -ComObject ("WScript.Shell")
 | 
				
			||||||
 | 
					$ShortCut = $Shell.CreateShortcut("$env:Public\Desktop\$name.url")
 | 
				
			||||||
 | 
					$ShortCut.TargetPath="$url"
 | 
				
			||||||
 | 
					$ShortCut.Save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# arguements:  -name {{shortcut name}}   -url {{url}}
 | 
				
			||||||
							
								
								
									
										12
									
								
								update.sh
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								update.sh
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SCRIPT_VERSION="121"
 | 
					SCRIPT_VERSION="122"
 | 
				
			||||||
SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/update.sh'
 | 
					SCRIPT_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/update.sh'
 | 
				
			||||||
LATEST_SETTINGS_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/api/tacticalrmm/tacticalrmm/settings.py'
 | 
					LATEST_SETTINGS_URL='https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/api/tacticalrmm/tacticalrmm/settings.py'
 | 
				
			||||||
YELLOW='\033[1;33m'
 | 
					YELLOW='\033[1;33m'
 | 
				
			||||||
@@ -184,14 +184,14 @@ if ! [[ $HAS_PY39 ]]; then
 | 
				
			|||||||
  sudo rm -rf Python-3.9.2 Python-3.9.2.tgz
 | 
					  sudo rm -rf Python-3.9.2 Python-3.9.2.tgz
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
HAS_NATS220=$(/usr/local/bin/nats-server -version | grep v2.2.3)
 | 
					HAS_NATS220=$(/usr/local/bin/nats-server -version | grep v2.2.6)
 | 
				
			||||||
if ! [[ $HAS_NATS220 ]]; then
 | 
					if ! [[ $HAS_NATS220 ]]; then
 | 
				
			||||||
  printf >&2 "${GREEN}Updating nats to v2.2.3${NC}\n"
 | 
					  printf >&2 "${GREEN}Updating nats to v2.2.6${NC}\n"
 | 
				
			||||||
  nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
 | 
					  nats_tmp=$(mktemp -d -t nats-XXXXXXXXXX)
 | 
				
			||||||
  wget https://github.com/nats-io/nats-server/releases/download/v2.2.3/nats-server-v2.2.3-linux-amd64.tar.gz -P ${nats_tmp}
 | 
					  wget https://github.com/nats-io/nats-server/releases/download/v2.2.6/nats-server-v2.2.6-linux-amd64.tar.gz -P ${nats_tmp}
 | 
				
			||||||
  tar -xzf ${nats_tmp}/nats-server-v2.2.3-linux-amd64.tar.gz -C ${nats_tmp}
 | 
					  tar -xzf ${nats_tmp}/nats-server-v2.2.6-linux-amd64.tar.gz -C ${nats_tmp}
 | 
				
			||||||
  sudo rm -f /usr/local/bin/nats-server
 | 
					  sudo rm -f /usr/local/bin/nats-server
 | 
				
			||||||
  sudo mv ${nats_tmp}/nats-server-v2.2.3-linux-amd64/nats-server /usr/local/bin/
 | 
					  sudo mv ${nats_tmp}/nats-server-v2.2.6-linux-amd64/nats-server /usr/local/bin/
 | 
				
			||||||
  sudo chmod +x /usr/local/bin/nats-server
 | 
					  sudo chmod +x /usr/local/bin/nats-server
 | 
				
			||||||
  sudo chown ${USER}:${USER} /usr/local/bin/nats-server
 | 
					  sudo chown ${USER}:${USER} /usr/local/bin/nats-server
 | 
				
			||||||
  rm -rf ${nats_tmp}
 | 
					  rm -rf ${nats_tmp}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1946
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1946
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -10,33 +10,27 @@
 | 
				
			|||||||
    "test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
 | 
					    "test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\""
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@quasar/extras": "^1.10.4",
 | 
					    "@quasar/extras": "^1.10.5",
 | 
				
			||||||
    "apexcharts": "^3.23.1",
 | 
					    "apexcharts": "^3.23.1",
 | 
				
			||||||
    "axios": "^0.21.1",
 | 
					    "axios": "^0.21.1",
 | 
				
			||||||
    "dotenv": "^8.2.0",
 | 
					    "dotenv": "^8.2.0",
 | 
				
			||||||
    "prismjs": "^1.22.0",
 | 
					    "prismjs": "^1.22.0",
 | 
				
			||||||
    "qrcode.vue": "^1.7.0",
 | 
					    "qrcode.vue": "^1.7.0",
 | 
				
			||||||
    "quasar": "^1.15.13",
 | 
					    "quasar": "^1.15.18",
 | 
				
			||||||
    "vue-apexcharts": "^1.6.0",
 | 
					    "vue-apexcharts": "^1.6.0",
 | 
				
			||||||
    "vue-prism-editor": "^1.2.2"
 | 
					    "vue-prism-editor": "^1.2.2"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "@quasar/app": "^2.2.6",
 | 
					    "@quasar/app": "^2.2.7",
 | 
				
			||||||
    "@quasar/cli": "^1.1.3",
 | 
					    "@quasar/cli": "^1.2.0",
 | 
				
			||||||
    "core-js": "^3.11.2",
 | 
					    "core-js": "^3.13.0",
 | 
				
			||||||
    "eslint-plugin-cypress": "^2.11.2",
 | 
					    "eslint-plugin-cypress": "^2.11.2",
 | 
				
			||||||
    "flush-promises": "^1.0.2",
 | 
					    "flush-promises": "^1.0.2",
 | 
				
			||||||
    "fs-extra": "^9.1.0"
 | 
					    "fs-extra": "^9.1.0"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "browserslist": [
 | 
					  "browserslist": [
 | 
				
			||||||
    "last 4 Chrome versions",
 | 
					    "last 3 Chrome versions",
 | 
				
			||||||
    "last 4 Firefox versions",
 | 
					    "last 3 Firefox versions",
 | 
				
			||||||
    "last 2 Edge versions",
 | 
					    "last 2 Edge versions"
 | 
				
			||||||
    "last 3 Safari versions",
 | 
					 | 
				
			||||||
    "last 3 Android versions",
 | 
					 | 
				
			||||||
    "last 3 ChromeAndroid versions",
 | 
					 | 
				
			||||||
    "last 3 FirefoxAndroid versions",
 | 
					 | 
				
			||||||
    "last 3 iOS versions",
 | 
					 | 
				
			||||||
    "last 2 Opera versions"
 | 
					 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -261,6 +261,9 @@
 | 
				
			|||||||
                  @click="eventLogMoreInfo(props.row)"
 | 
					                  @click="eventLogMoreInfo(props.row)"
 | 
				
			||||||
                  >Last Output</span
 | 
					                  >Last Output</span
 | 
				
			||||||
                >
 | 
					                >
 | 
				
			||||||
 | 
					                <span v-else-if="props.row.check_type === 'diskspace' || props.row.check_type === 'winsvc'">{{
 | 
				
			||||||
 | 
					                  props.row.more_info
 | 
				
			||||||
 | 
					                }}</span>
 | 
				
			||||||
              </q-td>
 | 
					              </q-td>
 | 
				
			||||||
              <q-td>{{ props.row.last_run || "Never" }}</q-td>
 | 
					              <q-td>{{ props.row.last_run || "Never" }}</q-td>
 | 
				
			||||||
              <q-td v-if="props.row.assigned_task !== null && props.row.assigned_task.length > 1"
 | 
					              <q-td v-if="props.row.assigned_task !== null && props.row.assigned_task.length > 1"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
    @input="value => $emit('input', value)"
 | 
					    @input="value => $emit('input', value)"
 | 
				
			||||||
    :rules="[...validationRules]"
 | 
					    :rules="[...validationRules]"
 | 
				
			||||||
    reactive-rules
 | 
					    reactive-rules
 | 
				
			||||||
 | 
					    autogrow
 | 
				
			||||||
  />
 | 
					  />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <q-toggle
 | 
					  <q-toggle
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -94,7 +94,7 @@
 | 
				
			|||||||
                <q-item-section>Global Settings</q-item-section>
 | 
					                <q-item-section>Global Settings</q-item-section>
 | 
				
			||||||
              </q-item>
 | 
					              </q-item>
 | 
				
			||||||
              <!-- code sign -->
 | 
					              <!-- code sign -->
 | 
				
			||||||
              <q-item v-if="!noCodeSigning" clickable v-close-popup @click="showCodeSign = true">
 | 
					              <q-item v-if="!hosted" clickable v-close-popup @click="showCodeSign = true">
 | 
				
			||||||
                <q-item-section>Code Signing</q-item-section>
 | 
					                <q-item-section>Code Signing</q-item-section>
 | 
				
			||||||
              </q-item>
 | 
					              </q-item>
 | 
				
			||||||
            </q-list>
 | 
					            </q-list>
 | 
				
			||||||
@@ -124,7 +124,7 @@
 | 
				
			|||||||
          </q-menu>
 | 
					          </q-menu>
 | 
				
			||||||
        </q-btn>
 | 
					        </q-btn>
 | 
				
			||||||
        <!-- help -->
 | 
					        <!-- help -->
 | 
				
			||||||
        <q-btn size="md" dense no-caps flat label="Help">
 | 
					        <q-btn v-if="!hosted" size="md" dense no-caps flat label="Help">
 | 
				
			||||||
          <q-menu auto-close>
 | 
					          <q-menu auto-close>
 | 
				
			||||||
            <q-list dense style="min-width: 100px">
 | 
					            <q-list dense style="min-width: 100px">
 | 
				
			||||||
              <q-item clickable v-close-popup @click="openHelp('docs')">
 | 
					              <q-item clickable v-close-popup @click="openHelp('docs')">
 | 
				
			||||||
@@ -272,8 +272,8 @@ export default {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    noCodeSigning() {
 | 
					    hosted() {
 | 
				
			||||||
      return this.$store.state.noCodeSign;
 | 
					      return this.$store.state.hosted;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -136,7 +136,7 @@ export default {
 | 
				
			|||||||
    getOptions() {
 | 
					    getOptions() {
 | 
				
			||||||
      this.getClients();
 | 
					      this.getClients();
 | 
				
			||||||
      this.getSites();
 | 
					      this.getSites();
 | 
				
			||||||
      this.agentOptions = Object.freeze(this.getAgentOptions());
 | 
					      this.agentOptions = this.getAgentOptions();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    show() {
 | 
					    show() {
 | 
				
			||||||
      this.$refs.dialog.show();
 | 
					      this.$refs.dialog.show();
 | 
				
			||||||
@@ -152,7 +152,7 @@ export default {
 | 
				
			|||||||
      this.hide();
 | 
					      this.hide();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  created() {
 | 
				
			||||||
    this.getOptions();
 | 
					    this.getOptions();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // copy prop data locally
 | 
					    // copy prop data locally
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -143,7 +143,7 @@ export default {
 | 
				
			|||||||
    getOptions() {
 | 
					    getOptions() {
 | 
				
			||||||
      this.getClients();
 | 
					      this.getClients();
 | 
				
			||||||
      this.getSites();
 | 
					      this.getSites();
 | 
				
			||||||
      this.agentOptions = Object.freeze(this.getAgentOptions());
 | 
					      this.agentOptions = this.getAgentOptions();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    show() {
 | 
					    show() {
 | 
				
			||||||
      this.$refs.dialog.show();
 | 
					      this.$refs.dialog.show();
 | 
				
			||||||
@@ -159,7 +159,7 @@ export default {
 | 
				
			|||||||
      this.hide();
 | 
					      this.hide();
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  created() {
 | 
				
			||||||
    this.getOptions();
 | 
					    this.getOptions();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // copy prop data locally
 | 
					    // copy prop data locally
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -111,6 +111,7 @@
 | 
				
			|||||||
                dense
 | 
					                dense
 | 
				
			||||||
                options-dense
 | 
					                options-dense
 | 
				
			||||||
                outlined
 | 
					                outlined
 | 
				
			||||||
 | 
					                clearable
 | 
				
			||||||
                v-model="template.action"
 | 
					                v-model="template.action"
 | 
				
			||||||
                :options="scriptOptions"
 | 
					                :options="scriptOptions"
 | 
				
			||||||
                map-options
 | 
					                map-options
 | 
				
			||||||
@@ -174,6 +175,7 @@
 | 
				
			|||||||
                dense
 | 
					                dense
 | 
				
			||||||
                options-dense
 | 
					                options-dense
 | 
				
			||||||
                outlined
 | 
					                outlined
 | 
				
			||||||
 | 
					                clearable
 | 
				
			||||||
                v-model="template.resolved_action"
 | 
					                v-model="template.resolved_action"
 | 
				
			||||||
                :options="scriptOptions"
 | 
					                :options="scriptOptions"
 | 
				
			||||||
                map-options
 | 
					                map-options
 | 
				
			||||||
@@ -696,4 +698,4 @@ export default {
 | 
				
			|||||||
    if (this.editing) Object.assign(this.template, this.alertTemplate);
 | 
					    if (this.editing) Object.assign(this.template, this.alertTemplate);
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,6 +138,7 @@
 | 
				
			|||||||
            v-model="localField.default_value_string"
 | 
					            v-model="localField.default_value_string"
 | 
				
			||||||
            :rules="[...defaultValueRules]"
 | 
					            :rules="[...defaultValueRules]"
 | 
				
			||||||
            reactive-rules
 | 
					            reactive-rules
 | 
				
			||||||
 | 
					            autogrow
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        </q-card-section>
 | 
					        </q-card-section>
 | 
				
			||||||
        <q-card-section>
 | 
					        <q-card-section>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -73,7 +73,12 @@
 | 
				
			|||||||
            label="Collector Task"
 | 
					            label="Collector Task"
 | 
				
			||||||
            v-model="collector"
 | 
					            v-model="collector"
 | 
				
			||||||
            class="q-pb-sm"
 | 
					            class="q-pb-sm"
 | 
				
			||||||
            @input="autotask.custom_field = null"
 | 
					            @input="
 | 
				
			||||||
 | 
					              () => {
 | 
				
			||||||
 | 
					                autotask.custom_field = null;
 | 
				
			||||||
 | 
					                autotask.collector_all_ouput = false;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
          <q-select
 | 
					          <q-select
 | 
				
			||||||
            v-if="collector"
 | 
					            v-if="collector"
 | 
				
			||||||
@@ -87,6 +92,13 @@
 | 
				
			|||||||
            options-dense
 | 
					            options-dense
 | 
				
			||||||
            hint="The last line of script output will be saved to custom field selected"
 | 
					            hint="The last line of script output will be saved to custom field selected"
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
 | 
					          <q-checkbox
 | 
				
			||||||
 | 
					            v-if="collector"
 | 
				
			||||||
 | 
					            dense
 | 
				
			||||||
 | 
					            label="Save all output (Only for text area)"
 | 
				
			||||||
 | 
					            v-model="autotask.collector_all_output"
 | 
				
			||||||
 | 
					            class="q-py-sm"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
        </q-card-section>
 | 
					        </q-card-section>
 | 
				
			||||||
        <q-card-section>
 | 
					        <q-card-section>
 | 
				
			||||||
          <q-select
 | 
					          <q-select
 | 
				
			||||||
@@ -229,6 +241,7 @@ export default {
 | 
				
			|||||||
        task_type: "scheduled",
 | 
					        task_type: "scheduled",
 | 
				
			||||||
        timeout: 120,
 | 
					        timeout: 120,
 | 
				
			||||||
        alert_severity: "info",
 | 
					        alert_severity: "info",
 | 
				
			||||||
 | 
					        collector_all_output: false,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      policyChecks: [],
 | 
					      policyChecks: [],
 | 
				
			||||||
      severityOptions: [
 | 
					      severityOptions: [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,6 +90,13 @@
 | 
				
			|||||||
            options-dense
 | 
					            options-dense
 | 
				
			||||||
            hint="The return value of script will be saved to custom field selected"
 | 
					            hint="The return value of script will be saved to custom field selected"
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
 | 
					          <q-checkbox
 | 
				
			||||||
 | 
					            v-if="collector"
 | 
				
			||||||
 | 
					            dense
 | 
				
			||||||
 | 
					            label="Save all output (Only for text area)"
 | 
				
			||||||
 | 
					            v-model="autotask.collector_all_output"
 | 
				
			||||||
 | 
					            class="q-py-sm"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
        </q-card-section>
 | 
					        </q-card-section>
 | 
				
			||||||
        <q-card-section>
 | 
					        <q-card-section>
 | 
				
			||||||
          <q-input
 | 
					          <q-input
 | 
				
			||||||
@@ -131,6 +138,7 @@ export default {
 | 
				
			|||||||
        alert_severity: null,
 | 
					        alert_severity: null,
 | 
				
			||||||
        timeout: 120,
 | 
					        timeout: 120,
 | 
				
			||||||
        custom_field: null,
 | 
					        custom_field: null,
 | 
				
			||||||
 | 
					        collector_all_output: false,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      collector: false,
 | 
					      collector: false,
 | 
				
			||||||
      customFieldOptions: [],
 | 
					      customFieldOptions: [],
 | 
				
			||||||
@@ -197,6 +205,7 @@ export default {
 | 
				
			|||||||
    this.autotask.alert_severity = this.task.alert_severity;
 | 
					    this.autotask.alert_severity = this.task.alert_severity;
 | 
				
			||||||
    this.autotask.timeout = this.task.timeout;
 | 
					    this.autotask.timeout = this.task.timeout;
 | 
				
			||||||
    this.autotask.custom_field = this.task.custom_field;
 | 
					    this.autotask.custom_field = this.task.custom_field;
 | 
				
			||||||
 | 
					    this.autotask.collector_all_output = this.task.collector_all_output;
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
@@ -72,18 +72,18 @@ export default {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    isValidThreshold(warning, error, diskcheck = false) {
 | 
					    isValidThreshold(warning, error, diskcheck = false) {
 | 
				
			||||||
      if (warning === 0 && error === 0) {
 | 
					      if (warning === 0 && error === 0) {
 | 
				
			||||||
        Notify.create(notifyErrorConfig("Warning Threshold or Error Threshold need to be set", 2000));
 | 
					        Notify.create({ type: "negative", timeout: 2000, message: "Warning Threshold or Error Threshold need to be set" });
 | 
				
			||||||
        return false
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (!diskcheck && warning > error && warning > 0 && error > 0) {
 | 
					      if (!diskcheck && warning > error && warning > 0 && error > 0) {
 | 
				
			||||||
        Notify.create(notifyErrorConfig("Warning Threshold must be less than Error Threshold", 2000));
 | 
					        Notify.create({ type: "negative", timeout: 2000, message: "Warning Threshold must be less than Error Threshold" });
 | 
				
			||||||
        return false
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (diskcheck && warning < error && warning > 0 && error > 0) {
 | 
					      if (diskcheck && warning < error && warning > 0 && error > 0) {
 | 
				
			||||||
        Notify.create(notifyErrorConfig("Warning Threshold must be more than Error Threshold", 2000));
 | 
					        Notify.create({ type: "negative", timeout: 2000, message: "Warning Threshold must be more than Error Threshold" });
 | 
				
			||||||
        return false
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ export default function () {
 | 
				
			|||||||
      defaultAgentTblTab: "server",
 | 
					      defaultAgentTblTab: "server",
 | 
				
			||||||
      clientTreeSort: "alphafail",
 | 
					      clientTreeSort: "alphafail",
 | 
				
			||||||
      clientTreeSplitter: 11,
 | 
					      clientTreeSplitter: 11,
 | 
				
			||||||
      noCodeSign: false,
 | 
					      hosted: false,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    getters: {
 | 
					    getters: {
 | 
				
			||||||
      clientTreeSplitterModel(state) {
 | 
					      clientTreeSplitterModel(state) {
 | 
				
			||||||
@@ -159,8 +159,8 @@ export default function () {
 | 
				
			|||||||
      SET_CLIENT_TREE_SORT(state, val) {
 | 
					      SET_CLIENT_TREE_SORT(state, val) {
 | 
				
			||||||
        state.clientTreeSort = val
 | 
					        state.clientTreeSort = val
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      SET_NO_CODE_SIGN(state, val) {
 | 
					      SET_HOSTED(state, val) {
 | 
				
			||||||
        state.noCodeSign = val
 | 
					        state.hosted = val
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    actions: {
 | 
					    actions: {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -742,7 +742,7 @@ export default {
 | 
				
			|||||||
        this.$store.commit("SET_AGENT_DBLCLICK_ACTION", r.data.dbl_click_action);
 | 
					        this.$store.commit("SET_AGENT_DBLCLICK_ACTION", r.data.dbl_click_action);
 | 
				
			||||||
        this.$store.commit("SET_URL_ACTION", r.data.url_action);
 | 
					        this.$store.commit("SET_URL_ACTION", r.data.url_action);
 | 
				
			||||||
        this.$store.commit("setShowCommunityScripts", r.data.show_community_scripts);
 | 
					        this.$store.commit("setShowCommunityScripts", r.data.show_community_scripts);
 | 
				
			||||||
        this.$store.commit("SET_NO_CODE_SIGN", r.data.no_code_sign);
 | 
					        this.$store.commit("SET_HOSTED", r.data.hosted);
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    showToggleMaintenance(node) {
 | 
					    showToggleMaintenance(node) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user