From 5fade89e2d89e62a2a8e168cc16730af6bc0d6eb Mon Sep 17 00:00:00 2001 From: silversword411 Date: Sun, 21 Nov 2021 15:18:18 -0500 Subject: [PATCH 01/48] docs - fixing install and restore docs to eliminate confusion --- docs/docs/install_server.md | 12 +++--- docs/docs/restore.md | 82 +++++++++++++++++++++++++++++++++---- 2 files changed, 82 insertions(+), 12 deletions(-) diff --git a/docs/docs/install_server.md b/docs/docs/install_server.md index af46f09e9a..f9c3d53f79 100644 --- a/docs/docs/install_server.md +++ b/docs/docs/install_server.md @@ -32,7 +32,7 @@ Install on a VPS: DigitalOcean, Linode, Vultr, BuyVM (highly recommended), Hetzn Use something that meets [minimum specs](install_server.md#hardware-os) -### Run updates and setup the linux user +### Run Updates on OS SSH into the server as **root**. @@ -46,6 +46,8 @@ apt -y upgrade If a new kernel is installed, then reboot the server with the `reboot` command +### Create a linux user + Create a linux user named `tactical` to run the rmm and add it to the sudoers group. **For Ubuntu**: @@ -63,11 +65,8 @@ usermod -a -G sudo tactical ``` !!!tip - [Enable passwordless sudo to make your life easier](https://linuxconfig.org/configure-sudo-without-password-on-ubuntu-20-04-focal-fossa-linux) + [Enable passwordless sudo to make your life easier in the future](https://linuxconfig.org/configure-sudo-without-password-on-ubuntu-20-04-focal-fossa-linux) -!!!note - You will never login to the server again as `root` again unless something has gone horribly wrong, and you're working with the developers. - ### Setup the firewall (optional but highly recommended) !!!info @@ -101,6 +100,9 @@ Enable and activate the firewall ufw enable && ufw reload ``` +!!!note + You will never login to the server again as `root` again unless something has gone horribly wrong, and you're working with the developers. + ### Create the A records We'll be using `example.com` as our domain for this example. diff --git a/docs/docs/restore.md b/docs/docs/restore.md index 9ab4e9aec6..367e759a59 100644 --- a/docs/docs/restore.md +++ b/docs/docs/restore.md @@ -8,13 +8,79 @@ Make sure you update your old RMM to the latest version using the `update.sh` script and then run a fresh backup to use with this restore script. -## Prepare the new server +## Install the new server -Create the same exact linux user account as you did when you installed the original server. +### Run Updates on OS -Add it to the sudoers group and setup the firewall. +SSH into the server as **root**. -Refer to the [installation instructions](install_server.md) for steps on how to do all of the above. +Download and run the prereqs and latest updates + +```bash +apt update +apt install -y wget curl sudo +apt -y upgrade +``` + +If a new kernel is installed, then reboot the server with the `reboot` command + +### Create a linux user + +Create a linux user named `tactical` to run the rmm and add it to the sudoers group. + +**For Ubuntu**: + +```bash +adduser tactical +usermod -a -G sudo tactical +``` + +**For Debian**: + +```bash +useradd -m -s /bin/bash tactical +usermod -a -G sudo tactical +``` + +!!!tip + [Enable passwordless sudo to make your life easier in the future](https://linuxconfig.org/configure-sudo-without-password-on-ubuntu-20-04-focal-fossa-linux) + +### Setup the firewall (optional but highly recommended) + +!!!info + Skip this step if your VM is __not__ publicly exposed to the world e.g. running behind NAT. You should setup the firewall rules in your router instead (ports 22, 443 and 4222 TCP). + +```bash +ufw default deny incoming +ufw default allow outgoing +ufw allow https +ufw allow proto tcp from any to any port 4222 +``` + +!!!info + SSH (port 22 tcp) is only required for you to remotely login and do basic linux server administration for your rmm. It is not needed for any agent communication.
+Allow ssh from everywhere (__not__ recommended) + +```bash +ufw allow ssh +``` + +Allow ssh from only allowed IP's (__highly__ recommended) + +```bash +ufw allow proto tcp from X.X.X.X to any port 22 +ufw allow proto tcp from X.X.X.X to any port 22 +``` + +Enable and activate the firewall + +```bash +ufw enable && ufw reload +``` + +!!!note + You will never login to the server again as `root` again unless something has gone horribly wrong, and you're working with the developers. + ## Change DNS A records @@ -24,16 +90,18 @@ Change the 3 A records `rmm`, `api` and `mesh` and point them to the public IP o ## Run the restore script -Copy the backup tar file you created during [backup](backup.md) to the new server. +1. Make sure you're logged in with the non-root user (eg `tactical`) + +2. Copy the backup tar file you created during [backup](backup.md) to the new server. -Download the restore script. +3. Download the restore script. ```bash wget https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/restore.sh chmod +x restore.sh ``` -Call the restore script, passing it the backup file as the first argument: +4. Call the restore script, passing it the backup file as the first argument: ```bash ./restore.sh rmm-backup-XXXXXXXXX.tar From e5b8fd67c8c87c02db48b6ca31dbf8fe73e01687 Mon Sep 17 00:00:00 2001 From: tremor021 Date: Mon, 22 Nov 2021 02:14:11 +0100 Subject: [PATCH 02/48] Update Defender script --- scripts/Win_Defender_Enable.ps1 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/Win_Defender_Enable.ps1 b/scripts/Win_Defender_Enable.ps1 index 028f114beb..963ad1e312 100644 --- a/scripts/Win_Defender_Enable.ps1 +++ b/scripts/Win_Defender_Enable.ps1 @@ -1,3 +1,6 @@ +# User should pass 1 as argument to the script if Controlled Folder Access should be set +$CFAccess = $args[0] + # Verifies that script is running on Windows 10 or greater function Check-IsWindows10 { @@ -92,8 +95,11 @@ if (!(Check-IsWindows10-1709)) Write-Host # `nUpdating Windows Defender Exploit Guard settings`n# -ForegroundColor Green - Write-Host # Enabling Controlled Folder Access and setting to block mode# - Set-MpPreference -EnableControlledFolderAccess Enabled + if ($CFAccess -Eq 1) # Check if user has passed 1 to enable Controlled Folder Access + { + Write-Host # Enabling Controlled Folder Access and setting to block mode# + Set-MpPreference -EnableControlledFolderAccess Enabled + } Write-Host # Enabling Network Protection and setting to block mode# Set-MpPreference -EnableNetworkProtection Enabled From de2972631f7d2245c8afdd73421558719bc9aadc Mon Sep 17 00:00:00 2001 From: silversword411 Date: Sun, 21 Nov 2021 23:02:47 -0500 Subject: [PATCH 03/48] docs - tips about running scripts syntax --- .../images/tipsntricks_script_syntaxhelp.png | Bin 0 -> 7373 bytes docs/docs/tipsntricks.md | 10 ++++++++++ 2 files changed, 10 insertions(+) create mode 100644 docs/docs/images/tipsntricks_script_syntaxhelp.png diff --git a/docs/docs/images/tipsntricks_script_syntaxhelp.png b/docs/docs/images/tipsntricks_script_syntaxhelp.png new file mode 100644 index 0000000000000000000000000000000000000000..0735560491b7f22d5b4bcf73e2a7b031ce2669a6 GIT binary patch literal 7373 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 literal 0 HcmV?d00001 diff --git a/docs/docs/tipsntricks.md b/docs/docs/tipsntricks.md index 8b4e7c8b4f..0dfea7dc8c 100644 --- a/docs/docs/tipsntricks.md +++ b/docs/docs/tipsntricks.md @@ -42,3 +42,13 @@ Right-click the connect button in *Take Control* for connect options 6. Ok your way out +## Scripts + +### When Running Scripts + +Use the (i) at the end of the script name to: + +- Hover: see script parameter syntax help +- Left Click: Opens the script source in Github + +![Script Parameter Syntax](images/tipsntricks_script_syntaxhelp.png) From e97a5fef9481479d721d02229ea02db19c9775bc Mon Sep 17 00:00:00 2001 From: silversword411 Date: Mon, 22 Nov 2021 00:14:19 -0500 Subject: [PATCH 04/48] script library - adding syntax to tooltip helper --- api/tacticalrmm/scripts/community_scripts.json | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/api/tacticalrmm/scripts/community_scripts.json b/api/tacticalrmm/scripts/community_scripts.json index 5c8c84b834..3becc8da9a 100644 --- a/api/tacticalrmm/scripts/community_scripts.json +++ b/api/tacticalrmm/scripts/community_scripts.json @@ -184,7 +184,7 @@ "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. ", + "description": "Returns Screenconnect GUID for client - Use with Custom Fields for later use.", "args": [ "{{client.ScreenConnectService}}" ], @@ -196,7 +196,7 @@ "filename": "Win_Teamviewer_Get_ID.ps1", "submittedBy": "https://github.com/silversword411", "name": "TeamViewer - Get ClientID for client", - "description": "Returns Teamviwer ClientID for client - Use with Custom Fields for later use. ", + "description": "Returns Teamviwer ClientID for client - Use with Custom Fields for later use.", "shell": "powershell", "category": "TRMM (Win):Collectors" }, @@ -205,7 +205,7 @@ "filename": "Win_AnyDesk_Get_Anynet_ID.ps1", "submittedBy": "https://github.com/meuchels", "name": "AnyDesk - Get AnyNetID for client", - "description": "Returns AnyNetID for client - Use with Custom Fields for later use. ", + "description": "Returns AnyNetID for client - Use with Custom Fields for later use.", "shell": "powershell", "category": "TRMM (Win):Collectors" }, @@ -262,6 +262,7 @@ "submittedBy": "https://github.com/subzdev", "name": "Software Uninstaller - list, find, and uninstall most software", "description": "Allows listing, finding and uninstalling most software on Windows. There will be a best effort to uninstall silently if the silent uninstall string is not provided.", + "syntax": "-list \n[-u ]\n[-u quiet ]", "shell": "powershell", "category": "TRMM (Win):3rd Party Software", "default_timeout": "600" @@ -272,6 +273,7 @@ "submittedBy": "https://github.com/jhtechIL/", "name": "BitDefender Gravity Zone Install", "description": "Installs BitDefender Gravity Zone, requires client custom field setup. See script comments for details", + "syntax": "[-log]", "args": [ "-url {{client.bdurl}}", "-exe {{client.bdexe}}" @@ -374,6 +376,7 @@ "submittedBy": "https://github.com/dinger1986", "name": "Defender - Status Report", "description": "This will check for Malware and Antispyware within the last 24 hours and display, otherwise will report as Healthy. Command Parameter: (number) if provided will check that number of days back in the log.", + "syntax": "[]", "shell": "powershell", "category": "TRMM (Win):Security>Antivirus" }, @@ -409,6 +412,7 @@ "filename": "Win_Display_Message_To_User.ps1", "submittedBy": "https://github.com/bradhawkins85", "name": "Message Popup To User", + "syntax": "", "description": "Displays a popup message to the currently logged on user", "shell": "powershell", "category": "TRMM (Win):Other" @@ -418,6 +422,7 @@ "filename": "Win_Antivirus_Verify.ps1", "submittedBy": "https://github.com/beejayzed", "name": "Antivirus - Verify Status", + "syntax": "[-antivirusName ]", "description": "Verify and display status for all installed Antiviruses", "shell": "powershell", "category": "TRMM (Win):Security>Antivirus" @@ -799,6 +804,7 @@ "submittedBy": "https://github.com/tremor021", "name": "EXAMPLE File Copying using powershell", "description": "Reference Script: Will need manual tweaking, for copying files/folders from paths/websites to local", + "syntax": "-source \n-destination \n[-recursive {True | False}]", "shell": "powershell", "category": "TRMM (Win):Misc>Reference", "default_timeout": "1" @@ -818,6 +824,7 @@ "filename": "Win_AD_Join_Computer.ps1", "submittedBy": "https://github.com/rfost52", "name": "AD - Join Computer to Domain", + "syntax": "-domain \n-password \n-UserAccount ADMINaccount\n[-OUPath ]", "description": "Join computer to a domain in Active Directory", "shell": "powershell", "category": "TRMM (Win):Active Directory", @@ -828,6 +835,7 @@ "filename": "Win_Collect_System_Report_And_Email.ps1", "submittedBy": "https://github.com/rfost52", "name": "Collect System Report and Email", + "syntax": "-agentname \n-file \n-fromaddress \n-toaddress \n-smtpserver \n-password \n-port ", "description": "Generates a system report in HTML format, then emails it", "shell": "powershell", "category": "TRMM (Win):Other", From 3684fc80f021b64caea2d55e43caf1160a5ff067 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Mon, 22 Nov 2021 08:07:49 -0500 Subject: [PATCH 05/48] docs - spellchecking --- docs/docs/install_docker.md | 4 ++-- docs/docs/install_server.md | 4 ++-- docs/docs/update_docker.md | 2 +- docs/docs/update_server.md | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/docs/install_docker.md b/docs/docs/install_docker.md index 8523cc18e9..146b5da900 100644 --- a/docs/docs/install_docker.md +++ b/docs/docs/install_docker.md @@ -9,7 +9,7 @@ Install docker We'll be using `example.com` as our domain for this example. !!!info - The RMM uses 3 different sites. The Vue frontend e.g. `rmm.example.com` which is where you'll be accesing your RMM from the browser, the REST backend e.g. `api.example.com` and Meshcentral e.g. `mesh.example.com` + The RMM uses 3 different sites. The Vue frontend e.g. `rmm.example.com` which is where you'll be accessing your RMM from the browser, the REST backend e.g. `api.example.com` and Meshcentral e.g. `mesh.example.com` 1. Get the public IP of your server with `curl https://icanhazip.tacticalrmm.io` 2. Open the DNS manager of wherever the domain you purchased is hosted. @@ -34,7 +34,7 @@ We're using the [DNS-01 challenge method](https://letsencrypt.org/docs/challenge #### a. Deploy the TXT record in your DNS manager !!!warning - TXT records can take anywhere from 1 minute to a few hours to propogate depending on your DNS provider.
+ TXT records can take anywhere from 1 minute to a few hours to propagate depending on your DNS provider.
You should verify the TXT record has been deployed first before pressing Enter.
A quick way to check is with the following command:
`dig -t txt _acme-challenge.example.com`
or test using: Enter: `_acme-challenge.example.com` diff --git a/docs/docs/install_server.md b/docs/docs/install_server.md index f9c3d53f79..7938e5a4b4 100644 --- a/docs/docs/install_server.md +++ b/docs/docs/install_server.md @@ -108,7 +108,7 @@ ufw enable && ufw reload We'll be using `example.com` as our domain for this example. !!!info - The RMM uses 3 different sites. The Vue frontend e.g. `rmm.example.com` which is where you'll be accesing your RMM from the browser, the REST backend e.g. `api.example.com` and Meshcentral e.g. `mesh.example.com` + The RMM uses 3 different sites. The Vue frontend e.g. `rmm.example.com` which is where you'll be accessing your RMM from the browser, the REST backend e.g. `api.example.com` and Meshcentral e.g. `mesh.example.com` 1. Get the public IP of your server with `curl https://icanhazip.tacticalrmm.io` 2. Open the DNS manager of wherever the domain you purchased is hosted. @@ -139,7 +139,7 @@ Answer the initial questions when prompted. Replace `example.com` with your doma ### Deploy the TXT record in your DNS manager for Lets Encrypt wildcard certs !!!warning - TXT records can take anywhere from 1 minute to a few hours to propogate depending on your DNS provider.
+ TXT records can take anywhere from 1 minute to a few hours to propagate depending on your DNS provider.
You should verify the TXT record has been deployed first before pressing Enter.
A quick way to check is with the following command:
`dig -t txt _acme-challenge.example.com`
or test using: Enter: `_acme-challenge.example.com` diff --git a/docs/docs/update_docker.md b/docs/docs/update_docker.md index 021b7d54c2..e170c808a0 100644 --- a/docs/docs/update_docker.md +++ b/docs/docs/update_docker.md @@ -26,7 +26,7 @@ To renew your Let's Encrypt wildcard cert, run the following command, replacing sudo certbot certonly --manual -d *.example.com --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges dns -m admin@example.com --no-eff-email ``` -Verify the domain with the TXT record. Once issued, run the below commands to base64 encode the certificates and add then to the .env file +Verify the domain with the TXT record. Once issued, run the below commands to base64 encode the certificates and add them to the .env file ```bash echo "CERT_PUB_KEY=$(sudo base64 -w 0 /etc/letsencrypt/live/${rootdomain}/fullchain.pem)" >> .env diff --git a/docs/docs/update_server.md b/docs/docs/update_server.md index 35b67c9bb4..7bcf92778d 100644 --- a/docs/docs/update_server.md +++ b/docs/docs/update_server.md @@ -45,7 +45,7 @@ You can pass the optional `--force` flag to the update script to forcefully run ./update.sh --force ``` -This is usefull for a botched update that might have not completed fully. +This is useful for a botched update that might have not completed fully. The update script will also fix any permissions that might have gotten messed up during a botched update, or if you accidentally ran the update script as the `root` user. @@ -67,7 +67,7 @@ To renew your Let's Encrypt wildcard cert, run the following command, replacing sudo certbot certonly --manual -d *.example.com --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges dns -m admin@example.com --no-eff-email ``` -Same instructions as during install for [verifying the TXT record](install_server.md#deploy-the-txt-record-in-your-dns-manager) has propogated before hitting Enter. +Same instructions as during install for [verifying the TXT record](install_server.md#deploy-the-txt-record-in-your-dns-manager) has propagated before hitting Enter. After this you have renewed the cert, simply run the `update.sh` script, passing it the `--force` flag. From 17cc0cd09c7abeca38ff73cbc3fd3c52077a992d Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Mon, 22 Nov 2021 17:18:58 +0000 Subject: [PATCH 06/48] forgot to check core settings fixes #816 --- api/tacticalrmm/agents/management/commands/update_agents.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/api/tacticalrmm/agents/management/commands/update_agents.py b/api/tacticalrmm/agents/management/commands/update_agents.py index 0e7e769876..d5f52c4565 100644 --- a/api/tacticalrmm/agents/management/commands/update_agents.py +++ b/api/tacticalrmm/agents/management/commands/update_agents.py @@ -3,6 +3,7 @@ from packaging import version as pyver from agents.models import Agent +from core.models import CoreSettings from agents.tasks import send_agent_update_task from tacticalrmm.utils import AGENT_DEFER @@ -11,6 +12,10 @@ class Command(BaseCommand): help = "Triggers an agent update task to run" def handle(self, *args, **kwargs): + core = CoreSettings.objects.first() + if not core.agent_auto_update: # type: ignore + return + q = Agent.objects.defer(*AGENT_DEFER).exclude(version=settings.LATEST_AGENT_VER) agent_ids: list[str] = [ i.agent_id From 514713e8834a44b50b4fea55f04f1b7ad17d40dd Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Mon, 22 Nov 2021 17:23:38 +0000 Subject: [PATCH 07/48] don't log swagger --- api/tacticalrmm/tacticalrmm/middleware.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api/tacticalrmm/tacticalrmm/middleware.py b/api/tacticalrmm/tacticalrmm/middleware.py index c398a77bb8..90e41791d2 100644 --- a/api/tacticalrmm/tacticalrmm/middleware.py +++ b/api/tacticalrmm/tacticalrmm/middleware.py @@ -21,6 +21,7 @@ def get_debug_info(): f"/{settings.ADMIN_URL}", "/logout", "/agents/installer", + "/api/schema", ) From 489bc9c3b3164048b4a637dd2f44f6662619a01d Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Mon, 22 Nov 2021 17:24:48 +0000 Subject: [PATCH 08/48] optimize some queries --- api/tacticalrmm/agents/tasks.py | 5 ++--- api/tacticalrmm/core/tasks.py | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/api/tacticalrmm/agents/tasks.py b/api/tacticalrmm/agents/tasks.py index 83c46ad67f..bd98daad93 100644 --- a/api/tacticalrmm/agents/tasks.py +++ b/api/tacticalrmm/agents/tasks.py @@ -15,6 +15,7 @@ from agents.models import Agent from agents.utils import get_winagent_url +from tacticalrmm.utils import AGENT_DEFER def agent_update(agent_id: str, force: bool = False) -> str: @@ -311,9 +312,7 @@ def prune_agent_history(older_than_days: int) -> str: @app.task def handle_agents_task() -> None: - q = Agent.objects.prefetch_related("pendingactions", "autotasks").only( - "pk", "agent_id", "version", "last_seen", "overdue_time", "offline_time" - ) + q = Agent.objects.defer(*AGENT_DEFER) agents = [ i for i in q diff --git a/api/tacticalrmm/core/tasks.py b/api/tacticalrmm/core/tasks.py index cc0a061b08..6d1781b088 100644 --- a/api/tacticalrmm/core/tasks.py +++ b/api/tacticalrmm/core/tasks.py @@ -9,6 +9,7 @@ from core.models import CoreSettings from logs.tasks import prune_debug_log, prune_audit_log from tacticalrmm.celery import app +from tacticalrmm.utils import AGENT_DEFER @app.task @@ -58,9 +59,7 @@ def core_maintenance_tasks(): def cache_db_fields_task(): from agents.models import Agent - for agent in Agent.objects.prefetch_related("winupdates", "pendingactions").only( - "pending_actions_count", "has_patches_pending", "pk" - ): + for agent in Agent.objects.defer(*AGENT_DEFER): agent.pending_actions_count = agent.pendingactions.filter( status="pending" ).count() From 2c8f207454884fa47ce245e4c3a6567e44cbd47b Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Mon, 22 Nov 2021 20:26:10 +0000 Subject: [PATCH 09/48] add mgmt command to bulk delete agents --- .../management/commands/bulk_delete_agents.py | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 api/tacticalrmm/agents/management/commands/bulk_delete_agents.py diff --git a/api/tacticalrmm/agents/management/commands/bulk_delete_agents.py b/api/tacticalrmm/agents/management/commands/bulk_delete_agents.py new file mode 100644 index 0000000000..9c1cb15c2c --- /dev/null +++ b/api/tacticalrmm/agents/management/commands/bulk_delete_agents.py @@ -0,0 +1,81 @@ +import asyncio + +from django.core.management.base import BaseCommand +from django.utils import timezone as djangotime +from packaging import version as pyver + +from agents.models import Agent +from tacticalrmm.utils import AGENT_DEFER, reload_nats + + +class Command(BaseCommand): + help = "Delete old agents" + + def add_arguments(self, parser): + parser.add_argument( + "--days", + type=int, + help="Delete agents that have not checked in for this many days", + ) + parser.add_argument( + "--agentver", + type=str, + help="Delete agents that equal to or less than this version", + ) + parser.add_argument( + "--delete", + action="store_true", + help="This will delete agents", + ) + + def handle(self, *args, **kwargs): + days = kwargs["days"] + agentver = kwargs["agentver"] + delete = kwargs["delete"] + + if not days and not agentver: + self.stdout.write( + self.style.ERROR("Must have at least one parameter: days or agentver") + ) + return + + q = Agent.objects.defer(*AGENT_DEFER) + + agents = [] + if days: + overdue = djangotime.now() - djangotime.timedelta(days=days) + agents = [i for i in q if i.last_seen < overdue] + + if agentver: + agents = [i for i in q if pyver.parse(i.version) <= pyver.parse(agentver)] + + if not agents: + self.stdout.write(self.style.ERROR("No agents matched")) + return + + deleted_count = 0 + for agent in agents: + s = f"{agent.hostname} | Version {agent.version} | Last Seen {agent.last_seen} | {agent.client} > {agent.site}" + if delete: + s = "Deleting " + s + self.stdout.write(self.style.SUCCESS(s)) + asyncio.run(agent.nats_cmd({"func": "uninstall"}, wait=False)) + try: + agent.delete() + except Exception as e: + err = f"Failed to delete agent {agent.hostname}: {str(e)}" + self.stdout.write(self.style.ERROR(err)) + else: + deleted_count += 1 + else: + self.stdout.write(self.style.WARNING(s)) + + if delete: + reload_nats() + self.stdout.write(self.style.SUCCESS(f"Deleted {deleted_count} agents")) + else: + self.stdout.write( + self.style.SUCCESS( + "The above agents would be deleted. Run again with --delete to actually delete them." + ) + ) From 5107db6169af9d1bcfb869e4de788d70dcf06b14 Mon Sep 17 00:00:00 2001 From: sadnub Date: Tue, 23 Nov 2021 20:29:33 -0500 Subject: [PATCH 10/48] add drf_spectacular to dev requirements --- .devcontainer/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.devcontainer/requirements.txt b/.devcontainer/requirements.txt index 131d71795d..10ac780896 100644 --- a/.devcontainer/requirements.txt +++ b/.devcontainer/requirements.txt @@ -35,3 +35,4 @@ Pygments mypy pysnooper isort +drf_spectacular From b8eda37339fafb517c695f2abb441ba0e39a0420 Mon Sep 17 00:00:00 2001 From: sadnub Date: Tue, 23 Nov 2021 20:46:45 -0500 Subject: [PATCH 11/48] Fix setting alert template when policy assignment changes --- api/tacticalrmm/agents/models.py | 6 +----- api/tacticalrmm/automation/tasks.py | 2 ++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/api/tacticalrmm/agents/models.py b/api/tacticalrmm/agents/models.py index d7f695c04d..550cccacf2 100644 --- a/api/tacticalrmm/agents/models.py +++ b/api/tacticalrmm/agents/models.py @@ -98,7 +98,7 @@ def save(self, *args, **kwargs): # check if new agent has been created # or check if policy have changed on agent - # or if site has changed on agent and if so generate-policies + # or if site has changed on agent and if so generate policies # or if agent was changed from server or workstation if ( not old_agent @@ -109,10 +109,6 @@ def save(self, *args, **kwargs): ): generate_agent_checks_task.delay(agents=[self.pk], create_tasks=True) - # calculate alert template for new agents - if not old_agent: - self.set_alert_template() - def __str__(self): return self.hostname diff --git a/api/tacticalrmm/automation/tasks.py b/api/tacticalrmm/automation/tasks.py index 348cf235f8..a19c7456a4 100644 --- a/api/tacticalrmm/automation/tasks.py +++ b/api/tacticalrmm/automation/tasks.py @@ -54,6 +54,8 @@ def generate_agent_checks_task( if create_tasks: agent.generate_tasks_from_policies() + agent.set_alert_template() + return "ok" From 1a9e8742f7867b90dc22efb66552444b1e66d440 Mon Sep 17 00:00:00 2001 From: sadnub Date: Tue, 23 Nov 2021 21:12:05 -0500 Subject: [PATCH 12/48] remove the need to type agent name to delete agents in dashboard --- web/src/components/AgentTable.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/components/AgentTable.vue b/web/src/components/AgentTable.vue index f9338f9678..1b29069e8f 100644 --- a/web/src/components/AgentTable.vue +++ b/web/src/components/AgentTable.vue @@ -564,11 +564,11 @@ export default { removeAgent(agent) { this.$q .dialog({ - title: `Please type ${agent.hostname} to confirm deletion.`, + title: `Please type yes in the box below to confirm deletion.`, prompt: { model: "", type: "text", - isValid: val => val === agent.hostname, + isValid: val => val === "yes", }, cancel: true, ok: { label: "Uninstall", color: "negative" }, From 732afdb65db9e6fcc14d4445fe6265a4065352db Mon Sep 17 00:00:00 2001 From: sadnub Date: Tue, 23 Nov 2021 21:25:13 -0500 Subject: [PATCH 13/48] move custom fields to tab in edit agent modal --- web/src/components/modals/agents/EditAgent.vue | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/web/src/components/modals/agents/EditAgent.vue b/web/src/components/modals/agents/EditAgent.vue index 3d110df55c..1e0bfd3bcd 100644 --- a/web/src/components/modals/agents/EditAgent.vue +++ b/web/src/components/modals/agents/EditAgent.vue @@ -5,6 +5,7 @@ @@ -15,7 +16,7 @@ -
+
@@ -105,11 +106,18 @@ -
Custom Fields
+
+ + + +
+ No agent custom fields found. Go to **Settings > Global Settings > Custom Settings** +
+ From 6d0f9e2cd52c33a339dac9e70c158347d009591e Mon Sep 17 00:00:00 2001 From: silversword411 Date: Tue, 23 Nov 2021 23:33:25 -0500 Subject: [PATCH 14/48] docs - video embed testing --- docs/docs/backup.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/docs/backup.md b/docs/docs/backup.md index 6587faf525..bb9798308e 100644 --- a/docs/docs/backup.md +++ b/docs/docs/backup.md @@ -27,3 +27,9 @@ chmod +x backup.sh The backup tar file will be saved in `/rmmbackups` with the following format: `rmm-backup-CURRENTDATETIME.tar` + +## Video Walkthru + +
+ +
From 06f0fa8f0edcd001a27596f18c40c46828a91ea2 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Tue, 23 Nov 2021 23:37:54 -0500 Subject: [PATCH 15/48] Revert "docs - video embed testing" This reverts commit 6d0f9e2cd52c33a339dac9e70c158347d009591e. --- docs/docs/backup.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/docs/backup.md b/docs/docs/backup.md index bb9798308e..6587faf525 100644 --- a/docs/docs/backup.md +++ b/docs/docs/backup.md @@ -27,9 +27,3 @@ chmod +x backup.sh The backup tar file will be saved in `/rmmbackups` with the following format: `rmm-backup-CURRENTDATETIME.tar` - -## Video Walkthru - -
- -
From dcd8bee6765cc03ef2966d8280e5cf276118040b Mon Sep 17 00:00:00 2001 From: silversword411 Date: Tue, 23 Nov 2021 23:40:29 -0500 Subject: [PATCH 16/48] docs - video embed --- docs/docs/backup.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/docs/backup.md b/docs/docs/backup.md index 6587faf525..8276d33871 100644 --- a/docs/docs/backup.md +++ b/docs/docs/backup.md @@ -27,3 +27,9 @@ chmod +x backup.sh The backup tar file will be saved in `/rmmbackups` with the following format: `rmm-backup-CURRENTDATETIME.tar` + +## Video Walkthru + +
+ +
From 23fa0726d5af24e771935d433851e5363793ee34 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Wed, 24 Nov 2021 10:10:46 -0500 Subject: [PATCH 17/48] docs - v1 of getting started guide --- docs/docs/guide_gettingstarted.md | 25 +++++++++++++++++++++++++ docs/docs/install_considerations.md | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 docs/docs/guide_gettingstarted.md diff --git a/docs/docs/guide_gettingstarted.md b/docs/docs/guide_gettingstarted.md new file mode 100644 index 0000000000..0108e9b4ca --- /dev/null +++ b/docs/docs/guide_gettingstarted.md @@ -0,0 +1,25 @@ + +# TLRD Version + +## At Install + +Setup Email Alerts +Setup SMS Alerts +Setup Server Preferences +General +Time Zone +Clear faults on agents that haven't checked in after (days) + +Setup Automation Manager +Default Profile for workstations + + +## Every 75 days + +OS updates +reboot +Backup +TRMM Update + +## Biannually + diff --git a/docs/docs/install_considerations.md b/docs/docs/install_considerations.md index 3d1a768604..e74c2ff4f5 100644 --- a/docs/docs/install_considerations.md +++ b/docs/docs/install_considerations.md @@ -13,5 +13,5 @@ There's pluses and minuses to each install type. Be aware that: - Docker is more complicated in concept: has volumes and images - If you're running multiple apps it uses less resources in the long run because you only have one OS base files underlying many Containers/Apps -- Backup/restore is by via Docker methods only +- Backup/restore is via Docker methods only - Docker has container replication/mirroring options for redundancy/multiple servers From faa1a9312f8d00020cefec589cad2635f84be1c0 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Wed, 24 Nov 2021 11:25:15 -0500 Subject: [PATCH 18/48] scripts - adding parameter check --- scripts/Win_Defender_Enable.ps1 | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/scripts/Win_Defender_Enable.ps1 b/scripts/Win_Defender_Enable.ps1 index 963ad1e312..d82b82d7d1 100644 --- a/scripts/Win_Defender_Enable.ps1 +++ b/scripts/Win_Defender_Enable.ps1 @@ -1,5 +1,20 @@ -# User should pass 1 as argument to the script if Controlled Folder Access should be set -$CFAccess = $args[0] +<# + .SYNOPSIS + Enables Windows Defender and sets preferences to lock Defender down + .DESCRIPTION + Windows Defender in its default configuration does basic protections. Running this script will enable many additional settings to increase security. + .PARAMETER NoControlledFolders + Adding this parameter will not enable Controlled Folders + .EXAMPLE + -NoControlledFolders + .NOTES + 9/2021 v1 Initial release dinger1986 + 11/24/2021 v1.1 adding command parameters for Controller Folder access by Tremor and silversword + #> + +param ( + [switch] $NoControlledFolders +) # Verifies that script is running on Windows 10 or greater function Check-IsWindows10 @@ -95,10 +110,13 @@ if (!(Check-IsWindows10-1709)) Write-Host # `nUpdating Windows Defender Exploit Guard settings`n# -ForegroundColor Green - if ($CFAccess -Eq 1) # Check if user has passed 1 to enable Controlled Folder Access + if ($NoControlledFolders) # Check if user has run with -NoControlledFolders parameter { - Write-Host # Enabling Controlled Folder Access and setting to block mode# - Set-MpPreference -EnableControlledFolderAccess Enabled + Write-Host "Skipping enabling Controlled folders" + } + else { + Write-Host "Enabling Controlled folders" + Set-MpPreference -EnableControlledFolderAccess Enabled } Write-Host # Enabling Network Protection and setting to block mode# From 63474c2269f1ccf8eaf97ba86f811f4e350e4674 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Wed, 24 Nov 2021 11:30:03 -0500 Subject: [PATCH 19/48] community scripts - adding syntax to defender enable --- api/tacticalrmm/scripts/community_scripts.json | 1 + 1 file changed, 1 insertion(+) diff --git a/api/tacticalrmm/scripts/community_scripts.json b/api/tacticalrmm/scripts/community_scripts.json index 3becc8da9a..f5beddf121 100644 --- a/api/tacticalrmm/scripts/community_scripts.json +++ b/api/tacticalrmm/scripts/community_scripts.json @@ -286,6 +286,7 @@ "guid": "da51111c-aff6-4d87-9d76-0608e1f67fe5", "filename": "Win_Defender_Enable.ps1", "submittedBy": "https://github.com/dinger1986", + "syntax": "[-NoControlledFolders]", "name": "Defender - Enable", "description": "Enables Windows Defender and sets preferences", "shell": "powershell", From 026c259a2e423914e73c1f0fc978145a00c7504e Mon Sep 17 00:00:00 2001 From: silversword411 Date: Wed, 24 Nov 2021 11:32:04 -0500 Subject: [PATCH 20/48] added vscode spellcheck, shouldn't go public --- .vscode/settings.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8c7f149e3b..257644061d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -66,5 +66,10 @@ "usePlaceholders": true, "completeUnimported": true, "staticcheck": true, - } + }, + "cSpell.words": [ + "certbot", + "Meshcentral", + "TRMM" + ] } \ No newline at end of file From e80345295eae65b3913daa3bcb26ed11791047c2 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Wed, 24 Nov 2021 14:06:44 -0500 Subject: [PATCH 21/48] script library - adding security audit --- api/tacticalrmm/scripts/community_scripts.json | 9 +++++++++ {scripts_wip => scripts}/Win_Security_Audit.ps1 | 0 2 files changed, 9 insertions(+) rename {scripts_wip => scripts}/Win_Security_Audit.ps1 (100%) diff --git a/api/tacticalrmm/scripts/community_scripts.json b/api/tacticalrmm/scripts/community_scripts.json index f5beddf121..025254fcc8 100644 --- a/api/tacticalrmm/scripts/community_scripts.json +++ b/api/tacticalrmm/scripts/community_scripts.json @@ -698,6 +698,15 @@ "shell": "powershell", "category": "TRMM (Win):Security" }, + { + "guid": "43a3206d-f1cb-44ef-8405-aae4d33a0bad", + "filename": "Win_Security_Audit.ps1", + "submittedBy": "theinterwebs", + "name": "Windows Security - Security Audit", + "description": "Runs an Audit on many components of windows to check for security issues", + "shell": "powershell", + "category": "TRMM (Win):Security" + }, { "guid": "7ea6a11a-05c0-4151-b5c1-cb8af029299f", "filename": "Win_AzureAD_Check_Connection_Status.ps1", diff --git a/scripts_wip/Win_Security_Audit.ps1 b/scripts/Win_Security_Audit.ps1 similarity index 100% rename from scripts_wip/Win_Security_Audit.ps1 rename to scripts/Win_Security_Audit.ps1 From 9b4b729d193bcae9ae1e5978beceb4db648e3dc6 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Wed, 24 Nov 2021 17:12:58 -0500 Subject: [PATCH 22/48] undo vscode spellcheck --- .vscode/settings.json | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 257644061d..8c7f149e3b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -66,10 +66,5 @@ "usePlaceholders": true, "completeUnimported": true, "staticcheck": true, - }, - "cSpell.words": [ - "certbot", - "Meshcentral", - "TRMM" - ] + } } \ No newline at end of file From f998b28d0be1e43560d0154306c506080d55ea67 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Wed, 24 Nov 2021 17:34:43 -0500 Subject: [PATCH 23/48] docs - numbering fix --- docs/docs/restore.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/docs/restore.md b/docs/docs/restore.md index 367e759a59..3e85a5d47a 100644 --- a/docs/docs/restore.md +++ b/docs/docs/restore.md @@ -96,10 +96,8 @@ Change the 3 A records `rmm`, `api` and `mesh` and point them to the public IP o 3. Download the restore script. -```bash -wget https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/restore.sh -chmod +x restore.sh -``` + wget https://raw.githubusercontent.com/wh1te909/tacticalrmm/master/restore.sh + chmod +x restore.sh 4. Call the restore script, passing it the backup file as the first argument: From 6a2cd5c45a8bad6c8d309deb523842797fff6e18 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Thu, 25 Nov 2021 06:20:06 +0000 Subject: [PATCH 24/48] reduce celery memory usage and optimize a query --- api/tacticalrmm/logs/views.py | 12 +++++++++--- api/tacticalrmm/tacticalrmm/celery.py | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/api/tacticalrmm/logs/views.py b/api/tacticalrmm/logs/views.py index bac5ca7b0f..8c6bc32104 100644 --- a/api/tacticalrmm/logs/views.py +++ b/api/tacticalrmm/logs/views.py @@ -9,7 +9,7 @@ from rest_framework.response import Response from rest_framework.views import APIView from rest_framework.exceptions import PermissionDenied -from tacticalrmm.utils import notify_error, get_default_timezone +from tacticalrmm.utils import notify_error, get_default_timezone, AGENT_DEFER from tacticalrmm.permissions import _audit_log_filter, _has_perm_on_agent from .models import AuditLog, PendingAction, DebugLog @@ -93,10 +93,16 @@ class PendingActions(APIView): def get(self, request, agent_id=None): if agent_id: - agent = get_object_or_404(Agent, agent_id=agent_id) + agent = get_object_or_404( + Agent.objects.defer(*AGENT_DEFER), agent_id=agent_id + ) actions = PendingAction.objects.filter(agent=agent) else: - actions = PendingAction.objects.filter_by_role(request.user) + actions = ( + PendingAction.objects.select_related("agent") + .defer("agent__services", "agent__wmi_detail") + .filter_by_role(request.user) # type: ignore + ) return Response(PendingActionSerializer(actions, many=True).data) diff --git a/api/tacticalrmm/tacticalrmm/celery.py b/api/tacticalrmm/tacticalrmm/celery.py index d307479ae4..cfee60b874 100644 --- a/api/tacticalrmm/tacticalrmm/celery.py +++ b/api/tacticalrmm/tacticalrmm/celery.py @@ -20,8 +20,9 @@ app.result_serializer = "json" # type: ignore app.task_serializer = "json" # type: ignore app.conf.task_track_started = True -app.autodiscover_tasks() app.conf.worker_proc_alive_timeout = 30 +app.conf.worker_max_tasks_per_child = 2 +app.autodiscover_tasks() app.conf.beat_schedule = { "auto-approve-win-updates": { From 31bb9c2197be2b8d7dd8ca34650fa217372a57f5 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Thu, 25 Nov 2021 08:59:21 -0500 Subject: [PATCH 25/48] docs - tips and tricks add mesh connection logs --- docs/docs/images/mesh_agent_onlineoffline.png | Bin 0 -> 25742 bytes docs/docs/tipsntricks.md | 8 ++++++-- 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 docs/docs/images/mesh_agent_onlineoffline.png diff --git a/docs/docs/images/mesh_agent_onlineoffline.png b/docs/docs/images/mesh_agent_onlineoffline.png new file mode 100644 index 0000000000000000000000000000000000000000..c0c7640e7ea2e2e42c050fe88a6438d9af1dedfc GIT binary patch literal 25742 zcmbTdby%Cv7Bw2Yg(58uMcYzbin}`$2v(dH4HPR-2u>-|;>9&ca4Qnr+mhmL!J)WI zaL7%6=iGD8_dVyYo9Bs4GVf$&@0tDXS!>M~?bphL_%!$c0Dw?cMF9u^V3wdimp#Bm zzbd-ntfSvB+=0q+fXbn#+vozeovfxT08kxEaQhYqU4H1QV&o105dHZ3#DKdLTLS>r z&r}s;^}NmZ+X%~T48cp14*6lM4j_F+1=Y~Juix~zN=fn(+1EL6l~YTw$aooE%wWiA zyt0mZ9A&!tS!T6?>U~ZsFE<0&j5Zj~7Q^>;VA@gFs)dTwYAuRzCJw_igLf^M?A=NA z64Jy@`sV(^J==e%=_1?xuxV2&_H4S%ZXY&%VRX{~ft^eFrq})F@uK$g#D59}|Gx_O zB@EXi;lL6-_9V3eUyD9veJ9-Yv4!@rO;S+KW!m}_4Lr0aU2!$}Zl?~RA%HS(o>=H*yv1^II zpr^7s#?6s^cDfE2D7PxH8Gk9w`^_1U%ePBX&+oGrmq7UEc|C`5#OXSe(US4!#6pW{dL|sYY6GW98ex&YAR;MdA)sR z59XgFXwF-a`i@>IzCd4#31bv_D3X5#6+V1J!;%5Vw2#~YLtJ3Y`N>wH{^>&haOy5wbIR=B8r+6-RO2 zIRRtF{uzVU;HB$s^F~cu1*YTVD>vgtIdW4Rs!{B0#FyyKIhl&K#*Y;>D zrX#@C=_$@nGX(|!FiEN9hi9Gk+r>SWl~_HN0ekCKj9$j>##icZGE861CICbUWHPd7P zwTy%Gpb?W`ut1V=)f7Ro{ojfA=VjS>t){KeNwR+MYxK0=$M1BJq0dx; zIAw1S>(g*vX~ms`(cB*a|nCFUg< z3S~1vHfjYQizE`SQAHTLe=Sy$Rj#l|TS|JDy_qE>(uC~(yS#t^J$ahoAL=o~tO{eTaguc@uw9Z|d2ZPO^czZboduEHJ>LGi?jUfnzo?8l8LDj92j+LJ^J6sx5EtEO0QN4 z%tr`xsp!7-{JW~012+MBBHEC~iS03IqCcrXq%P(+vR_J;T&={Syicd4Po52S@ee;* zbJF|k4a3>RvepOa#@D}b1#W)xWKT+0oW7k#A?7{%*anI3kEOZm-ndpz<_6wXWkm9{ zi%8hz|LxVkqm7C)m}-TT1yzd}rlUZCHR<>^&Q zTlrOF;4x26jvn$y2kIhY$^X1IgV=8w>#bPEXk1bzDNy%cQR!o3W#ie{Mj!-idm0Uw z`uIpGye`5fU>sdXInHNqruyGqnE1Nmn_@a9aanFB7AO0m7`lg zxa>cjH7h-UGsZzxZZ`!wSTP*=TZi#c1Zq9*T979D`OfESCtF76AS(}IWohrSt0 za}8BjD0D>ps0_h!Bs^RLN@D>&{Z!r}&pu z5bRlv=ZK9ehT{l6s^~iM{@X%L`JEN4&iMy=H*soImYbd5U*d(Bcdqy_CAs6SMfHJf zwy{3MhfD=D$~g3fH2Xxn9#sBsJ0tM#)&o(8{2d=1%97DNK7!^w0BVvlPRbUigabR~ zrL!#<l(OnN)JN?3A^m&cHTk#Gu8HS|LrMg%#yE*|D9gi=bp1o>AUestDPSW z4rxnu6>(xjU-FuNF5>mXPk+3;Ooi7L=}=3a#mJX(IBN292cladGyADqqHk~}se)cx zirc}@l+zicHu$VazB>Dzc8biPU8m@znaQ ziTVA>Vs(Y-hOiR@^!1FmaSF1i8xpQ370WYeNa!ukVI8xtYKArY;JyCCl1Lqo$65sj zM*nj4M#Uj&%EfcJMC^PdTmv7~jYC(x*Xww!h0hbe?8_H)OUMoX zWlpgD*lvN;@u{?h#l~>t-5uD=%zdz)>oj8nyQE~|_Wv;bpu-jtcv~~^i^uP+`=q{M z=w`0(L6hAadQPCTngZSbHi1wns4B&0?*4ADqG6FHy9`lj6QC>S;IRFFv>0ulJgvU+ zB6sXIZb z)4EW;<;$xHcWKNO4cLb{vP1H{(O$iB2YQiti9XRf} zI_MHJhuo|Eafxmp3Co^V-zWPUkqnh%!zfn=w}M|vvVG29dznSnqa1kb+aXL5n1syw zP(%j{*`A5t;-U{OJX`WwJk7prov>c;bDzmBTw}Pi_cKSwF;%BONT9ePzwC}-$MvM1 zLq9Sp)(_fpB=x3q+r_!bhUIRO;Z|01(-(Ct9TS>cwdg9(1M%&16IYTD4?lg_vLD6o zb8KkV(01Ty=KIEEBKx3yEoK8x`oi7H^{dqR;l0`Ec|%8AQ~u8{LkkbpR5ZCNoZJ3wtc7k4@urjjkhP}=E~By zE7#ICmk2wl@q*r~rwxq}jnG`T^1bBn4R!O2c@N!a-_!d$Gv8D;(|~>bD*V$UnjL9^ zXAG-4$>uG|HQGXu#pgO79UJgB+Axy<7P=~@36iIQpQ>rs6Qc%(q~9jWwalCR1i_qzF6CD3~X2LFlt z^bCg6)FUe9D*nKoqSCyz_@SFkRO?k1a2yrLKEL?%k;_`dA;Ni_IgfRBmj+{T+ur|c> zoCjqygStT71X}F&UQNt0K%ftR`cO@}{AP4|JUM#vwNHAGP*Hk3Y+nIPuY#TxS?|AN zQkYujNAmDG;C3px*#=L59Ue@PeE)9YCYvPL8cz>7h zOS3lq_RzQEGP2D*Z$03%p?>V!z>BuSN#4^& zOzKg`%A;;0G3b}glv_t?=ho`0e#-Xma*T!FWx<01uJ>1F_klOCD$m8$L#cIi-i6vk zmD_9&j3u4qAKZS!Ll!;_yvRD7;6<#X?suxrSD*3sU8EF2%*O@S{04t?VIKE8`!0t;gHdAs7RfyqsM^3OacOpjK+&Q? zeMG!atw=<*!CZxt%ZYcK6QPrlX29My-xx0~ZOas7j3-eU-csK**>nz~4sU;dmiFsc zekD@tZtpXs*}y;3cIb0J_yM?+lIeE(_VkEESoIAZvx8OM?FWh0TG zo#fr8jhL65v$=+)n3B_V^LGR0j3Dybbd(F2=0SgRp$#xC)mj5w`S zmZ}Lb&^`iK^@PrkDd2v1gNKFlG(y-qC^~ESNoz9YVHOuC!JL@I*;bfh>K}UWAf}48Nc7@v5Ai+=+T}@F5oucu4l5p zLuaZEvwy&rL~%Y=?p@=`Ut;AQFnWd7m{clw8&TRfX_rJ~@(-GY&nQe2D1v1UNchNhYFDE zTD1O)^!>^X-_J<(YZxacBl$JrGMxukMaLzCUXn<|Xh8rnv}O$T#Byj4JZOSF@@5)j zjr^tTV3rn1R>(8U_-qGBC+h_F1{Pzq|2d&1^g& z!jkZFEca*jd-CjWgR-!GWIui6gAtB_{Tf?gXgdeJ1ANV)uBp5xX1^a!08N%C-ldsP zo1Z9L$E)b$uBSbQBAV{~EIYf&A3VYZJmHrKx+Npi^VWp5?oF1%@%_@kB-lR(!WhX( zPEANl)tX_q6~d$#FKqE;jfHW9p_XMMi?bob=O+;|jucuiY~SMBynhBr$KVvNd{4Ur}U2Fr(H@F#m8H?nCTVK*i>aP$*c%w!7^as6hregO2p(oZBM zc3FtsO71?+NVj! zR+e6W!5OD!VdPCNOywk+A27m2IrWh?c*6css*mtvthiF)$MRQ>|CyR5OrB4lDB|Yh zN0Gmpt7Gm&(hp}V+30OWGfgJxpYE+j|C8TgO~T(LXk4;n8jzgx!L4FqXK6u zY`&7f;o6rsPc?CA<>N}%i?Yua zoe|;2kfG`6Fpv>1Lis;D#0x+JEsFirGjL z*dWjD;=CLdFS#ne+VVv?+b~cO#93R+aGF^~N(@puZjkeX_<_Cmjn8;XD18Um!~?^x zoyB*P5n^Ea86}k$eh*lcH_yi1!Ps&50z|SdIBF?N9$GshGo?>}l==3{>3i>5CgU8K zqi!RL%++Q3SGUA8s6uVFN@$VC zmLS|%Wf$s)mq^9y=0_Eb_QaNN<>QPk+$X{^!jgl&I0|8xT*nb3wI2X^%4V4vC+k^V zHBKi2#y^z8`?;<0cZ>}elv{OFe)(FV98Gr1n$NnpdOkVp@P0>T>kO7nOV>Eb+?X`H zvqVfkELp=8YWc`2EbSK?W_?Uj)jUp{YeU{iIXUe7J{6UBO2KA+Xlqk*vSmsQE-Si= zQ_>S&6y6_Ktw@$2eoqRGSyfiwT6q=t{7^MI8CAyOEpKK{9>cZx`EO#5-eeJ)CTLok z5SG|_j|Jgo+Zz^-yztA4J0^SMO)P{z0^p!)q}d~qbzrLs%^-6QW?h};Jyt-R@Q*dW z&BS_CqCC@(Ky5R51ePiFAv@+yh*=;>9kr#fXyZFCdwqS)CX+E7R5qn5Ilc2G%|NPk zd4sNW#BtyFe(ZG}Y$M-Bu{kmk~qF5gWGd>JWb?0=Vf(G&goylX@p zoT4g^taYoViz_95mA;+X<)yjCF@c#gfOF0Aq>j^5-KhdSP+}-%5Yv40>a|?>wiqi8 z@3WjJ$?uCMh%m2hnB|;!(eGeq^k@a94wy4K>z@Gq8-$i5FcNdC>w-8-zJoBjzc|L;e(xo;r_c$yDCR6e&EM=FvTzZ(8#l!3$Hip-X=f&* zU{X3HFW9l>ORf(g0TrW(!MksaF?ZN(%l2-!Wn{m%7vGqZE*0N2@gv}`_IoX&ZM^H&`=aeWZ}{$41c9eld?%@HpH_#q@~Qn8MRHMB zL-#@5$;v*49GO7*p+ig3$rFnd)cz_6;<%vZAE9nBQiQ0Q`pDj=c2|->$Ixs^8t&nM zg1tri;SlPdLOV$UJ)z6nzclGUIZt-Ai$@&e*w1V-u{{EVBho0O%Jx{u71uBuNBKma zFQ*@C`YO8a;6O2IJCiZqJg;R^(I@%SV!g4Mn#*@+)A4-zbO<+ZfveKcMan3Sr9j$) z^Mg-$vjp+;f6%HRuTErHYP5LJZJ_N!fN;8_)lEX-l z*R$D0%dKd|Hc>WVi$D5nt|8Cd!$9o6Ig7k% zH)Dnd6wxm5_#|069F@753s4FL((wn`kypt7XB#(+uYe$4Gny{-<->EM`tEV+EaKFw zm!Hz2(ngM?_`WErn?$$=lX4Y3B+mIYZsUEPhxiQbpWM+rB2m5)U`UQ>eHrfVC#f;c zm_!g4OpQcRI_zlOD3a{XE&asaor@004YW7BSISY51RS$!l5Z=cYv`&E`@YCK(aGKl z`_U7_VE7X+K+x&_<-kQO4`t1;Oe8h0!*NJ^GKV5FZ5kV~KDd1pU#@|r_5r>-NN(qdf#d{NmZ73E?_PTFj za-?}#jkzZVZQ~V+abgp~4pUk_t;vIvp*~xL7?{^#^(a=7>#Ov`Qab)MUpo%dRLKFA zY@L>Olf5ID)d3LCUkY;(D6UKqTl{)&Fs!_cdl>5$!EeQ#tPovN*;_2*@C zZV)ixc7B|ix~-VT2O~$$e?gDcn<#vhRm1ytzKhSDZVbrp#u>|nVhXGJ$r1p!DkBXe zM~>YM1KM1n;0%0V$h(_l#t1V!KWRudqyO_vBR3kwC3Q8$#r}r_R4fdXjkK!2Q{?)j z*FHyq8?jA@iE@vDfvWbuxVR$?vV6ZsB#kVky>QrHTK~H}&%nnOe!jx`yliou2LF=;GjYW@ zpG}@S;C=#Y4EHR%#!OQLYLM(zP?7_t2R_f6%@>bWeN^-#^Z*kzpW}?j#xveVS7n=p zZi{UoL{*vIFb$8vBh{{WPqt-iC(EcnMweWNfv94aKChd5G?YmI@zi2RnKafXY~*IE zBeg$}S{7z+wb*1gfl>F|rh^-5y97IGR8B?f6~Z_bAfx@B&OW2Lp)~LzmviX$`K{L7 zCTc#(t%03MFv<9PW$Q`bhVHPBf$*`$lkX>$DeVH-L(vhD-3wa&4ylyam*CCN&4T*Z zXUG>FxBZgZSx^qh&AeD)ULCMjc1IFZmIcy!*o`(6y zES$*m?ni0&Xu|8#m0Gz{pQOJAnj7M^q(M2Zi`&^;zf1GtnvV*o<=wEmVaS07k}prz z9g-nH7GOV;)i=Df?0w0SA&q-UdY*MmiK8!ORv6X-p^@olZrKq+jm?) zya-G)XBw(R%@Nx_6Ce`iLv|AR-HwSpHTaE%=Iz`O1Z&~uC*Q;jwrVdZw0k3`JTyZl zvavb&PBS%6D40X_a3uSQJF8Jw1m1ca02LqGjZnqYPZJ;#YOa-CQSwp(k@(n+xnD^I zPRMH}{fIsy!ua z->bdT@02_Jq=#I*a>63-o4YGb{LxK#^ney&<*+!Qx?P56yt}zcy!b)(Qi4f;O*e)+ zpu~OR;yMR(wyak-m~Uu4`*Lx&Wz5zmW+CxSht>SdR&*TQIBnj3s(XV;Hjef`;5gyp zLUF}=0`n^CglAqzjr&{J_gt?eZnYq#L!{=q+*-qXA&`Is>irP~mq^FWHe+YDH*QqK`Tga)P1jaAEvBaOHNugEXB3{xF zx22HXp>j?BI3dA%y#y(8F&Sx}6ng^i_8R*-B0+xKInRjv{mVC_jS_y-^}mTngDuz* ztPu;Y03A&#@QV4IQ7Kv^UI+sIZ{m^1AP8Q!Zk>Z?Pwf-mLAfZ6)wt#ToaMO;c<1E&{kl`qZ-P#h_S|3Xy%rsTh+(F7y_)F&jo$t;fonf5pZm8Z*yPQFJJu@JM zOa(intth3AoY_AOpsz`5`K-OGS}r?WFN*<2lnQ2jIXTFQsk$SK8&lvsHGG!PVU&ei zf;$z-!jAW)y#e&jp}>I zOX#wZLNoq#d>;8Du9urt!b_mM4i#M&7Lp}hE`n8Dy)|!)*?X3!Ri)vZ;D{zr8;5XN zUc_Hi@R{q=UoXe2VeS@~v&W_pQ2 zJ~;4y#XW2-@H&~t*)?a6YOz9DbCQ0e_UimSv^Lc2qj^hL=Zz&+rQu6C)YSah_7zs& z&V2(WU!ro#bJa+zplE8Zd#Sc&iAgz3X%ijIZoYI zh%o$BpY}8tVkCWuk-7Y0LFpLr(`g&^`v!M?{O+gIVk5TRiTiTObVuFS$JiRicVX8( zo057Rs`SMZ?~RACyksy;-bzsMDr=n7xofyE1LkvSp}DSoqT8)ThOQb>vIb8Y(`eL4 zXEmR#5qCBj2N*X( zq=@|dwf4|;#UJ}QvkRp#Z_t;GV9NN$=3#2;=Lm2>Y&{0=vB1;#!YT%E+RGV*Sy9|K zui3@jnb&cpzQ8T|@^4BXdwzEhmQ$arua2vat-A7#=h-xxt3k5$rSKwt_m#l?{P#@D zY9~Y81zoC)#+2&Bg(;!Y5z18iE}QWXBu?Pfd-(5=W(6xnNXSg|S8vOIL7kJjG+-m; z?a)ndtesZ=EB2Y5xSc-Z@u+^tUm`oiD|@VfE(q|W#YnbDCQRx@scT-`SB$6LEXM}y zK?r#s6{aK!0B3UjjyxIH(={DEd*CxOOI$#m2tLqTp3Td@Q6*<8BzKb3YB(jB)h6eb z#)}5}4o2_&Xua1c>cj)-s5uvBwIPeMF;H8^=yY>w@8YjW;-qTk1af--+@|D5RMZcb zSuBJo55X><8m_%D3(({7;Omq3Luq4C{^EAQ@Z@koPV`@XZ)cJm%nR~~{bEAR#7WC>sSMCHzFT`a6Eyi&{E`Pbc@k$~_aY|LSG&#?dS}NQd!Ya)9Z?fm z>l&B_1D8@u@W@xPvNrBi(OI#+&QGj4yb{v$m?@k4lB3P>f=BV2F#AqgVhh=4?&K6NVXBESUuvrTgU@w{dF!cF=$egqOO$6NlGDRCqVpsqpa?0E{bA%; zbXq+Fco-qmf{|~yIyfyj zer~he7t`aHTt9JiA|(#h5mQMy;)}Vl`4HJ+uCgDT7ilpZzyI)K%*M)%CmI>2rLUOw zx$e=p5l^|A=BYm(5oR}s*Xy_lY*z1lqF5Q-uuW@=O3b+XqLZmNU$w_S>7UDT?x_SS z|3)Fn-JtvUzi`G+UfcD{_ABWuLDU%QziAO#T5b7lYi4Q2-}ke0|Hue4dGgUXUWi71 z8L;fMB;zTTeee~a9?XfUf+f>hO;H%P18Frp8po>}$dm9nw0y)^eu~}y;p3$4DxME> z>ern`jrr`5K&x3pi260WHmi3{=pq6E;LZ|yw9K<&DH+}**D$lREhQlyohCR$6W zFQCq*o!RvzU-9ho+*!Wh8K3nAm`e+2F#=iz{GC0X=)na`EW+#ha+-m{sYIiRNtp; ztdPt;o%%DSSLw>ITm33}o1c|EsWwyf4XuN9UzE1S>%?Q76!Fr#B*7EMXvk<*`;<-(_ z?LEaKCC@mK z5}UF--XI|&;-XSumfxPART5kO&^HY966r@8dj=cuV=)`576WyRR!zX$$N$Ja#nBoY zso$i==YxU!MOnds?9XhUM zsQNiesNN9XlVJV9eu&i-y9VFe(>%MoP>Pcu1iez~Ctt>%y-vx-vafiyi5d4f!IqFC zu%!{LNBlMEL^Or_8|zKtYyIA$&x0EgL;JrXIw&CZuuGOc zRYV302%w(oIYQ*um!)7O)TbCK6O8LTe;+Jj@$_vT5FL(JGBkM4|PQ8C7im|dJ> z853KV&*M|@RNFgf>{$JG3fy&{uWBH?dT()$6gEp)U#=xzHru>-Vl^l8$o0f>8|O1& zml$(&u9Tip2dKjt8(8uz$9|Kr7hyeiavc{m5AtLtT91qw%u`*nB|jHXmWYc>M|d`) z?r$|EOYJq}s)I{^<9#A=RfR(b!LNj2758kwdPr!pAzY6#rm zw*o_B1mQd#eiapcgG9oqew0nUtA&mTFFhBr9q_tRcOcJ0!^5^;<06^z+3CrP%MwQe zc0%yOmMV@52pYjzs5Tl?o}aM4yCt0XBHYn5EmVkSe$i}B)1K**0512l@Hy`H3ePCu z*791@%qIR#HGK{(_jz{S8EHP@h&6uPa(Gbi_A2di&!rw_fzG51v+wq*C1Tsw=oUnE zGVJH*dEBw?>>$*J6dj8Z{0Ds&;?t`oXCkPZYepw=DP3jf(yIZBK%$j|oQ{&{DvS<*txHhPKOJR#zWx z+p7F*++ET#%jY-AJKJka0nTXoskvz+3WY{t1~V*9(@Fd=8VUOTsEA5x$6uh4ot@C* zs|{VP{ZOW{m@!6FnZ?nkY7do+>$|QryRda!8uD`0l(T#xCi-Ll8DxP!vDrtX(-=%_ z2A^K_Za-E^P#W=B2*J{d0s1Ve>sv{eO#B_o?GS8hMfBDoOn2fiHjDQ z5}wWsVtTian>Su@Z+}d3AeNf({gsM}S&fd3a-za#i{GXoTO~@{xXQv5GB}?L&JdD# zrO6Qg+WLLu=)Nqxs;z!W3DdPR{@{l}xDnAGI;_b)$!`4m7wiErN ztAUtU5&4vf!2aWjwJi|O*b3dzVOm1V7ZcFBHC{0Jy3EH+bT^yX7w+oGj zrqTMjHmg7W2Thyj-IurLudYB;%=@f_CmrQMd0OFhB}<+*AByIyz>{STX%+LESzhK& z(ve!tP#33@LNpH9v(9rI;o|oA?P0)0OGZoIFG4f$dXm+?e0E}_07!YYt;keC&_V%m z_QgedQ2s_i(=|XJbLyJ2q|+L13&4U45VpBg2vRI*g2Th0I zNp*m{@y9Xf0gMpw>K)=>yk~GT0CnMuG$;RiEJhJ>w`a#8gF$^i!)2GL^Ae*KPiS`6 zx(6Ht`PBh~+Q2<#(JIE9+emYP)M+Jao7fnxGJs^CgkzIS`_%?bO2_E2YR!2Xc1q;f z>%9yc@)7uja@$+enSI|-vL}~AM&1ivMB2$~`1ttmC=7lO08&AX`-2;eK0R-UglgM< zEs0(IsoaCGU745)BuaVmVL5nQnRaQn1q4CX-O-1JbbpZbVK78Gx>N1vnu}?gNapVN z*E?Zm+9^qLR(^tZPfD&APWFX240nV08P#`zyGwG*+KAoIiK+$;W`viqa`M!mhs7ny z$oNMGGjG*#joqJ3w#^b%Hq*^xn+t?tr{9UAY0o;in~Mz(^>zM%`J9RuUmte{K}a+t zuBfy4&$tzS&f%bCrX>^K_n6Y@^%7CYmPxEoObj0l91(!(j^g-Qf~5@3cO6_D8Z5d# zN1M$qI)6)BR)6FoMvRZf3W-RAYnIj?$UD?5$_MkaXGc*`Rj)*9XS`hNA_FNp zy<0p?UbBdB{G#LJ%=gUoF`79zlR0K#nv@nPs5;a&TH20|mUA$S0lt(Z#)!40C^W$$ zbBK@TuSiIyJDR+lim8=jC+-7fdDZ-fz*}%W)+;o7t|@Wchx6%WHJFC%Sb7!4bX_OB z>NmFXiG01<=op)?s*}%YwniHD7!1nYrQf{_RCp zX-j*z@SQx{#V&h@t#z`Hdv;Q6lh)EB8EVfj7Eb1IrB(NNhawg(uP4e6ch1A7N-x?Z zm&lNi16{gT*TbvIHo`{NwKD7^mB@wdlfQRUV=+Z6FQcE1QhA0ym+2xTur+?ywokkA zcblx7D(xZ>PXf1)ue`%0y@^4r+2-GYyOcSx)7XI3L+JEvdHUW>f%@(uRzbFOsGcOA z_A-^5=WtFTKX$xK3;(JWFj( z;g$VHU~RMM;cD8WPsazwS7dp}u;BBYgSsj(+r!#M^wp=9;}nPh=#R_M^_!stV+2B@ z|1I!)J#VO<%whvxUJM0f*cM%FV_p9Pz?(jm7P{!Y(mU8oxkyDXUKgn4K9zfXRJzM! z|9a8gz`giRV;+WC6{;m($ZT$yoPLi0TiHl>7^JcwjR>ThnwEV;;R*oMZBA`nR$w%GiBfUVOJM^hL$V z(UVxN;7TF$c=~50RVLd?F&;4@J$AD7mV4em0Af6hlune2v)$M&G@?k2X}#c{Q)m z2WuomZ&vD^RoKZH0-L7{_Lh%ex_Y$Bxy)FI+QQyE?yD<)dABbxelu89W+!?OM~mTw z6j4cddMzRjc`pTyV+Z1@i|yg z=&Hbu`@pyamOJflTgXQ zGbRqM@MM?#xKgJ@Uy*V;{<`pe)K8Crt@{Vc!C-06MLT$8bb{gHy^q3zI(l zMNLLh7Mh682%C_<32u5^e9n}_+c^~cR*ML?E$9c+gQsFj-gs^1`5%mp*zFxm@ha|I zgD1Y>dD7voPuP+X&PU@P;&`2Kh8zoHK0p6}pjTf#O7r$p;?$W9&B?IthrXN2nECVt zk61ggJrs0po(Os2%|UQec1y>o%kizNqZ7>o$s1&yS%+hYpm!&XngCUhqs{qe#%#iBGgyV0o zMm&ob0mPSCaJ>dCOPZ8pP#l54u7s6U+6gtM)mg?lU5{Ho+7n+N%}-i=ojhkn>W#P4 zI{uh)Fe<3vlsZ{c+Et<5ri$!yra?1Nw}uIBKU#B-X|WgM zThF8lj0-WF!dZK8EZPETAZ`_mn3glq5boV~o`ShQg&9W=Axosr{?crBKCJ_EuvUDX z^+5l0DdW|3UrV@Zm0UuhPSl6%^)2r9@SJy(H-?N;@CI5I!JW!Q$@T_gsf8062^?KS z&@~%?w$%w2i1f8sQ}=xXuHca%GtO|$Y+hw5!)lfmh4k?n)E z);ZlXnAecxl!R87aX@3_^Bx36x27k={78zs`}2)mofGESiL?r&sbV=Rk&VHEj=W$o$c!nFLRewJ?{wt zZp^QaVD&q}OgGwvRwF-#*Z#NBR8BIc7ClV%C%$F91fUt)KNlc(%_E!a04;+_5x09|x_! z;Dj>F!kUL+9~f-fDlr;rVj(LpUWP~TgFly^ot(bNd{)iGRaWqno~=*w%4s0&;zhG| z+Gv=mhlgmg&rYasu?uHl=is!je&~g(fr|j<^1hNYg=TYa7Sa}b^yT9Cm!L1KQhDVv z^UxEZmw~ZgGrOfXBAQ}*Mu>7%tCSXgN&na@`FuKwo~IjQW~&vEl9jwU~Z< zS9`SM@3QH#mP3nL#7EgCfN7bb+)iTU;)UCB=g;k_)Rto0e>j1z{RFZ=V*(`mKR4}tAAo_v zT$D&C_tVqk5-d=BVY1tl|+>;?Q+ z*5_FpPj_9^hkI!D<*z&?E^DwVrz{TbuOZGAw!H|am8&mwgMT?bj%b+x4IBMZ}bPE{>uG zDQjxiZAE$n0+Uwz-^P`g$e)=Z^1=wpL3d(2R-)!>Dea?ej-QQ8+W=*hu-*P|Vc<$w z)^4i(8v6)ls^A?k+voI|jUGDb`8r8!I=0*hgW6S&+y!~LyGTuL)N@q z&sxyuUWHgZKOWshI-gv{AfA2_d8x($3qT94=~Zw5@{P2=kfHPi;@dM1(2~}tVEH@n zKcd$E>tLT9iC3=B+v4e7?h}^K*OG;#k7aCE@b!X}$=c0T^m!_~UMMwjndWMx_>(gu zw@tCA7Gif~r@MFgRKta;T^V~d`a{BYqJ;2E(uK#?{je;Zo^@zV1y#!V(uNs!_uzDv z9&XcmCeL2N0?nW6mRvokvZ>Sm z1eWjUU@>rE)^c~SLf@%gq6I1&MfS_DN!6bVfwn%BFU`G?d|Sab!lvMG%VaM7 z65xPa{LK13OG0+OI!p_+(+H#(zcjGJ692q8 zJ@EhZb=GlBy>a^=AR&lD5kY|g1}Le5AdM0Z>F!WOU^oz^M+yi?D%~BUV{{4<4hdm| zqXY!p=om5TIq0{Z-|Kn(_V;#n&gVYoj_baz_wl=oCoyFf)`kdaTcH5cGMM*6Uc#{a zxZ_6y56^;lNmzB)IkliF`py$jHX$rL&UC!)sHZ;VGrQ)J(3eYMy(svAJI8$zC)*Aw znQ?mSSp{E*#r7kf_{%xJVw`@qnEE{9EvLLFQ@KVf;1urM{#tMU9Gq@c=#L} z#efPnuOakV3zw12Eope088MBhGJaB!X`)DDg;uroD~?_C{q26aT08Xlj5&SYswBoz zJKHD2=aMh=)wk6g=J6EB%3S-6qp2ZiHOuPIh-4DAIOjM|@M3>k^;J#Jx@%A!YvwH~ zN=@i|CTvF6?1#2wAH@>Z3+wFF14Xfvt}N`Pp8xW)G7>%bvj|+6Eu5#Q_5ytNPViu2 z94I|Qag z@7FbPyBt+a2{j*&bEG48?pqAE6_<)oi&VbPTjulb4C$iXg4?Hk)9x&u|!QCa}2~854UUq4yk;v~QakZiz5n<0A~M$-?du7lu-W%Of&3 z5I{!rV(xtb&;4He)yBQTEH64eKHn`)yE0w;>p)s4Zer() z+B-{q3eOe6G#iNPU{rm@=FuSKi-;n>z~kBP{i}UheA@>n0hRsd`xV1@fI8eG4)mB! zC0zmqbjRNr7WCoe_rC98ooOPJok?ts1Zh~^RNhrI#AbIaia(ibCj8`b>B^#^q4>3T z6dQ%EOo_w`_`_WFilvdeI)F7VELiPu#J)I(??AcN+RqLFy_=RN{WLLJ@yi(0SrRTLDw^VLD-p}QAG-~Uqm<9}u2YuqD3uoge4-OYyx?c7@ zEz)4~<1q=#7g4k<8fPhoKqZ~=NZXUR*Xob?nBiHT{Iq`!TWN~KHa=k5f6Vd42bLE8Y*mDC|erk}9*r6;y} zuW-hPe1hna)r9Db9kEBQe4DMvxB$|3HYTyuk2@NfowL-)^%IhacXJ%_1&y0t%<@ z6Fn0r9k6!b_R777hZ=P}x{*egXJ{ofS5a9OLvo(Sqm)tu9>-g0_EQIFy*}-hC7NuL ztF7NFeyQ!QrXV4D&A;Rc3i4fKt;FWhmgXH7$G%9PVd}RpD{uJ}bnU%-!LF8u+;xYF zgfQAjChB^1hKwL;@V+k1m81MJjg#!aoW?J&;=xGTwse{XxhkVKV5haK;LIr%>GSC! z+cf#9kW_s8v&F=IQa(MS>DW~xx&x*8e zp*X?!#)e`f+;C~u^DM&ETaI}rlD5KaZb9BL^N4(|eL07-LunZ10)hEpFSTUiX8lz&g~1?fs;ex#OF(x2-o*$H8yZt@ z*~DXGxd-3~>!v2_z+3j%!Cmm|vs@#-TG!DKsIRWk>(Qe|3Hjc3ganE~((&QsGM5Oh zAs@~Zf{|~(u+lEev|TJ6QJp(&ecfzvlJm&vu8izVdgWl=aW0v`1h&5-V(i?lp*7hTQ9Hkt4Zjgyg#bgY=Jg%WKrBrLg0~e)Er5SXNOEQ>HAMH$PhDPj4McE(u`Mx zn_87Q0F!8XL0yh$$f?5S`mJ%vna%eKxQfD`S_axf_IdC;DAK_5$atxWtj`H7Y;%Dv zpUc}D(p9ty2y}R;p%YDrRDQnw#;rkSO0>K?*138mAnCzTGf8pmyBNSPCXy_lm^U1N zLP`C!SW%CtyqUR@WavCKr9sSED%~8#MsJ~#J#zVql@r018%LJ7^#yX)r9$3+!Vp@> z;*ai*bps})KfmR#Rl|}B2h|u zC8W=>s!fiDpc`y7dXak8qs$7rYA|D61w$?94K=)C0!k7va0lZDJ#dt3!6oU~#2rtJ za8Q!5;9%ve6*5+yhWT8~*1v{NwzCneQe}Cfi-~|PI}R2`>?RMf*h$m76t~*WSS%(3 zFqw<2JlDcXc<&!o33Z`edqtmmVXXK(?BA?Ai*^a+upq;1iUFoaF(ad&b&~uI36@IN zGOdsp_ts(Nd^+DteW1^)EPmG;%`bXWVc+?{xwGHL(b7uhKi}ABv+;=a>AhsmYsN>@ z)hqD|*0laZe#VFdDFqIAV=EmX+M?5*+FH7Td58Nb-E!V?2LJ7+clyV>=||c3wj%NJ zY3lq0p?*@Nd;7zNrMnFYgN+7~-|n^)oC;D<$w3wgr|7-kTpJrf$bYal-yWJ%M)opkXcBJj&ym$B#;HQfl7LS z;+g*+Bc(PKZ`zmZZ%3y@S-0K80BQ~rXZ@G3X@LHKEz9&xGE83P;A?zqEf~cCezuVg z24647RC9y3#~?!!l=aEa4zV2*Ka?c>b2H`%Id3u71Sh3&mI!@5+5na8SBo4~Z5}lG zhPgTZ7|rv762({w?s4JPMvJ+(b;?6rDp>iZl^4|h-Ct!3V$-VUUIaR4oqM6{EJTxy z6}~1wh~>%-9~X-~xPBU+)&^&&I^m>2eNP`O%l?XI@!zQ?*CsTTO z$LrLE;#Av}18W+x!FjLg^U+#0ZtN$o77EZ?t<{h44{p2%jdd3q2vG%2&3zxr52bFp zn_XWqA~d(jmCdj4tyQJhtlo?US<}&ihJ6H`@vNe!Z&KMg1!S}Vn`UlL*pdeWQ$V4_ zRrKpmrKZ|jklFk6RQkeD9Ul@e?sGAl+~=_3qI@Nk8qI#XW{pLlD>EMb!%_Oa`I1&w zII8p_NZ;w2@)b&*%Xt&`uz(a1pt^#v4fz=OF6nV<`J*dEO?-`0GN?#&Ie%k(hrA(| zX`SWP%e7C{9|Kde=Ja-dtZvs-eC7U+YR2J{^7DJLYj}@+J(m;9A3%`ME3GB^o}mdh zvP{k?8(7aUOU;*vvtz3}e9CcO<5}*r%3*g}>DUeXdFUmgxTC5}pkq?4_e7^?#pC*4 zlF5Kd0<@$&r;*a(P%EsshE{`CW8p|=>093#F+knit$4^it=O6)$X-l-U%BU5q$Nbx zbM&ry_M#h^4@mh;wt`rdLWRt!Chv z#`BWVpD&a6U{1<>-fvcRu*3W?tC!{;cAbNCLVhvKwUwIk4*}QJrZh@+tw`nrzZ*Rz z8J0J6E!<0hgcJPy^R7=&EQ98SDRtY&f~{Ki4-T7E?9g!jq7{R5brQz8%H2oTH-~C5 z<+<%DO^9E?uLVoKq9XDGTW0R$EBsvPku%lxMz=67$k3O~f(@Z;AAg_pu&>PHxp@+n+E$e1^~9`Auo_2S*r54x{$t362twq$wuc&^EntjV zT*LM6@6W)6wWsaG)zaO3kJY8)8Sj$XF%Ytw#m;NLWKP^!wZJPHMfPQjso@z*72Px! z6}#Zc3Iqd7H%L4^-~!mv0-k`V9E37~!?$~TRr+3lwx>@!bE~z>(bhW*QT>yDlOs`v z1YwXRthi!FVj4) z1tyu|8I-ut56(b?KfH_6g~tiI&-x+pB^w->0I&a9&CkZ_)3 zP2H1oAVN->=;MRP6VVs@`Uyn>d`6QMW>@($^j55 z2G;$bAC~{L99S?L)hq__K-62f7y!eu%tsgHS>Iv3Z1a$}7$QEo6`FUvP!B5PPXSEC z+OWmnY8ZDFY5ig$BVmaC>pSu7W;&=NsN(6(3eq35E)gM zdU69nnvxYjWfW`OMFZIxT2ZesJ+h7IM7xJzq)GCSTB+s68Yd<&?=+=Xt;Ahb!EJHu ztEGzb)Klg{(=L@?|2FQdiA>4)+e#E;_{?)3SRXTTK{#g_RAe%m)vprRHDiwg*>y4o zKnylw)W}2o+?o8{hLKIx$KW;-R}yuJ=HVqCbsEPco1<0UjZA07999A5J7WP`pBrVk9KMdZz|>Bb+LfH7 zmkP~HNc7EUbEcGAM?)K-T|U}RFO~AA8*Rm)E@?8rNOaO`Rzvtsk`hGrP9vXnE7jv| zzyH?EW67vtEu@Lwz>ICTZu;bCy-^#+bsLaV9N!CT<#C3%;Jk*i|LJiaVa-F?uvDQ=-2ov&2if^bEl;LS6r^^m&PWDf&JKrKHU*JB^d;pq~#@8$YV`e8h_W zvo-b1@SfEL@xWs*Wo&>k+axps* z^uRP8e0cuoSq$|9q1I&i=q@j7^VrQoz&a`2OC3py#XOCD{UO(W6tmg$?*sC3mQgeF z>^RLDWoozqzpfDZv;bSX#f4CT7Vl%GddXGQ>&At)#XW@Lta#ND6 z4YM3%=Q$UP6w^sDjGlAbw2M)!#0ZPTG$Ts%q0^mLx*|7zGe?VkHoNcXi&Ye#(>?7O&~B2GT%Ub;ru( zfgC53Tr+!OVz~D`Gs$#{kM$GaY?udnX6BMZNj2?>Z39V_GcRln^ZJPa2>ut}$D-#j zC0VZ$NUkzZOym2s>KeIOb_dyRSpY!ZQ(hKwSbN8fyNVM5H|`(WuPPnxZ_Qrq`04Fe zMtGEM$8`sKv&8)dExYZZQ*P;iVxp^rq8i7=rTM4phG;p@hVAhcDnhX5EV^AgJ~zYY z?8`4{!eLmks$?LwIZlQInNzuB)iw{<;&viz6aT;bQJ%un238?n^9DP@S~J~cMrl6a zac4-K5WWdV^(=<=L@Kox&p&W6d`Mf3(4o6I;gwO+$q>|aE3T8WZH0r!bcvzL2_~Au z>+=_;R zqzSxpWI5EO)JQ72VUcs@t$A*`I?EPekkm|5>h)#9-&ge)XyeZfSs;*(J~3oj|K)23 zX&bK%a`YWdEJ0MT5!iJavrLoMo+g`R52ZO3bGy-rJmE=Oo^}K3^1qG%Gd_eFZAX3P zOx0gpe7CV?~M4QiJoZ5*gLo=Nor++N);{r%oCm``xBjO)(5= zf{B;oDpCM!=e`YhJVTdlhMv3wi~v29gfS&Mfib zTX|juE?;AtMO7PjkCyvK9QT!sr-lnQzIaRG%uaqi)`LE;YpTf;y5qUtqMt<9dSt|NMnz8q-wx?)?JAqA7vuXeT4u*N!r8O9>h9&aqeU0Mz%O;Qv`(Zv;q zHuNC?^uMKLR0^3=`ZsSn>2f4uQZVhiZ^7Aq7;2X=MxQ#+xGUma+2$N=%6*?c8zSz^ zdwTxBBscRn2O)7$x`i}9P;(e?>BIQ>f4DCd*Sy1JYu*CT8K>XFOl;49y=&d(e93xG zK?e(X#>VtITtffLQ`7%KR6oM>=&(7irBQUPaqFVGmey~cwR{rt4^q3h`k!siQ#3fR z?~MI-O7!OsV8EjKpZNFxsRo9(sY#BpY&_LW$PoHc$`c}PRTMg!Jj6PFeLh{vb_S8; zSJNY!n;(i)u{{+6Pa)kamw%73za!62JpM$UuYgG`Pb1G=?GH*ReX>v^gEMc=L>#S4 zNi+y?x9-e^Z)U50bOs2C&@M~mUfC*>zYfI>xDbT0AyS~PVKP-gkR@8g$Bu^ zK?AZ*;R%wP)RHJrj^EUMU}#&!NC??Qb{W>n;MK2ay*cg9f1l84A^ySpY5TkeZFZ8p ziVoj>AMUq7N5?2iwF0Nfzt-yjW&IoO_XkO?Ym`b^&7j%E;h@3+((PW>%Xewsb=?7m z4R=)wsFNjpD-?YiGqpMS^8yAeE1=;0>Gu0TK2B-Y(@S4O=`%*>MJA)f&Q}9ah~FLI zZ;<)#V}muhR#{U>eHJuUQq-=zJ<2{!OKvfZN7YkQ{M%!nHeHM%9H_);iZLQ~K*bMa z?Sr3jc;&rx#y)?mbJk#GRz-h7pSCWOjHCvs`ZjQYir7WzAg38YJaZdDX?&f3 z^72c>;w8}m6{tyQCsy*$-GKfNek5Ap|C2K0>B>-@*-vvrd~a&k zrK8T_-X{21Nu@wzA?i~@Vt+MT9JU%+v}@{SSGfqUL8Up@u4Eri ![Features](images/mesh_features.png) - 6. Ok your way out +### Agent online/offline logs + +In mesh from the agent | General Tab + +![online](images/mesh_agent_onlineoffline.png) ## Scripts ### When Running Scripts From 76d71beaa2b63c8e5273a73b9801e770a457a1f9 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Thu, 25 Nov 2021 15:06:15 -0500 Subject: [PATCH 26/48] script_wip addition --- scripts_wip/Win_Dell_Command_RunUpdate.bat | 1 + 1 file changed, 1 insertion(+) create mode 100644 scripts_wip/Win_Dell_Command_RunUpdate.bat diff --git a/scripts_wip/Win_Dell_Command_RunUpdate.bat b/scripts_wip/Win_Dell_Command_RunUpdate.bat new file mode 100644 index 0000000000..a4a288b54a --- /dev/null +++ b/scripts_wip/Win_Dell_Command_RunUpdate.bat @@ -0,0 +1 @@ +"c:\Program Files (x86)\Dell\CommandUpdate\dcu-cli.exe" /applyUpdates \ No newline at end of file From 7f4389ae081f31e41923f9f846ec6f79b1fa24c1 Mon Sep 17 00:00:00 2001 From: David Randall Date: Thu, 25 Nov 2021 16:59:19 -0500 Subject: [PATCH 27/48] Docs: Server services Document the server services and configuration. --- docs/docs/howitallworks.md | 307 +++++++++++++++++++++++++++++++++---- docs/mkdocs.yml | 11 +- 2 files changed, 290 insertions(+), 28 deletions(-) diff --git a/docs/docs/howitallworks.md b/docs/docs/howitallworks.md index 48125b83eb..b99cd0291d 100644 --- a/docs/docs/howitallworks.md +++ b/docs/docs/howitallworks.md @@ -15,41 +15,285 @@ Has a postgres database located here: !!!description A web interface for the postgres database -### Services +Dependencies from [here](https://github.com/wh1te909/tacticalrmm/blob/develop/api/tacticalrmm/requirements.txt) -nginx +### System Services -!!!description - Web server that handles https traffic +This lists the system services used by the server. -Log located at `/var/log/nginx` +#### nginx web server -```bash -tail /var/log/nginx -``` +Nginx is the web server for the `rmm`, `api`, and `mesh` domains. All sites redirect port 80 (HTTP) to port 443 (HTTPS). -### Dependencies from [here](https://github.com/wh1te909/tacticalrmm/blob/develop/api/tacticalrmm/requirements.txt) +!!! warning -[nats](https://nats.io/) + nginx does not serve the NATS service on port 4222. -How communication between client and server bride NAT (Network Address Translation) +???+ abstract "nginx configuration (a.k.a. sites available)" -[celery](https://github.com/celery/celery) + - [nginx configuration docs](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/) -!!!description - Used to schedule tasks to be sent to Agent + === ":material-web: `rmm.example.com`" + + This serves the frontend website that you intereact with. + + - Config: `/etc/nginx/sites-enabled/frontend.conf` + - root: `/var/www/rmm/dist` + - Access log: `/var/log/nginx/frontend-access.log` + - Error log: `/var/log/nginx/frontend-error.log` + - TLS certificate: `/etc/letsencrypt/live/example.com/fullchain.pem` + + === ":material-web: `api.example.com`" + + This serves the TRMM API for the frontend and agents. + + - Config: `/etc/nginx/sites-enabled/rmm.conf` + - roots: + - `/rmm/api/tacticalrmm/static/` + - `/rmm/api/tacticalrmm/tacticalrmm/private/` + - Upstreams: + - `unix://rmm/api/tacticalrmm/tacticalrmm.sock` + - `unix://rmm/daphne.sock` + - Access log: `/rmm/api/tacticalrmm/tacticalrmm/private/log/access.log` + - Error log: `/rmm/api/tacticalrmm/tacticalrmm/private/log/error.log` + - TLS certificate: `/etc/letsencrypt/live/example.com/fullchain.pem` + + === ":material-web: `mesh.example.com`" + + This serves MeshCentral for remote access. + + - Config: `/etc/nginx/sites-enabled/meshcentral.conf` + - Upstream: `http://127.0.0.1:4430/` + - Access log: `/var/log/nginx/access.log` (uses deafult) + - Error log: `/var/log/nginx/error.log` (uses deafult) + - TLS certificate: `/etc/letsencrypt/live/example.com/fullchain.pem` + + === ":material-web: default" + + This is the default site installed with nginx. This listens on port 80 only. + + - Config: `/etc/nginx/sites-enabled/default` + - root: `/var/www/rmm/dist` + - Access log: `/var/log/nginx/access.log` (uses deafult) + - Error log: `/var/log/nginx/error.log` (uses deafult) + +???+ note "systemd config" + + === ":material-console-line: status commands" + + - Status: `systemctl status --full nginx.service` + - Stop: `systemctl stop nginx.service` + - Start: `systemctl start nginx.service` + - Restart: `systemctl restart nginx.service` + - Restart: `systemctl reload nginx.service` reloads the config without restarting + - Test config: `nginx -t` + - Listening process: `ss -tulnp | grep nginx` + + === ":material-ubuntu: standard" + + - Service: `nginx.service` + - Address: `0.0.0.0` + - Port: 443 + - Exec: `/usr/sbin/nginx -g 'daemon on; master_process on;'` + - Version: 1.18.0 + + === ":material-docker: docker" + + TBD - To Be Documented + +#### Tactical RMM (Django uWSGI) service + +Built on the Django framework, the Tactical RMM service is the heart of system by serving the API for the frontend and agents. + +???+ note "systemd config" + + - [uWSGI docs](https://uwsgi-docs.readthedocs.io/en/latest/index.html) + + === ":material-console-line: status commands" + + - Status: `systemctl status --full rmm.service` + - Stop: `systemctl stop rmm.service` + - Start: `systemctl start rmm.service` + - Restart: `systemctl restart rmm.service` + - journalctl: + - "tail" the logs: `journalctl --identifier uwsgi --follow` + - View the logs: `journalctl --identifier uwsgi --since "30 minutes ago" | less` + + === ":material-ubuntu: standard" + + - Service: `rmm.service` + - Socket: `/rmm/api/tacticalrmm/tacticalrmm.sock` + - uWSGI config: `/rmm/api/tacticalrmm/app.ini` + - Log: None + - Journal identifier: `uwsgi` + - Version: 2.0.18 + + === ":material-docker: docker" + + TBD - To Be Documented + +#### Daphne: Django channels daemon + +[Daphne](https://github.com/django/daphne) is the official ASGI HTTP/WebSocket server maintained by the [Channels project](https://channels.readthedocs.io/en/stable/index.html). + +???+ note "systemd config" + + - Django [Channels configuration docs](https://channels.readthedocs.io/en/stable/topics/channel_layers.html) + + === ":material-console-line: status commands" + + - Status: `systemctl status --full daphne.service` + - Stop: `systemctl stop daphne.service` + - Start: `systemctl start daphne.service` + - Restart: `systemctl restart daphne.service` + - journalctl (this provides only system start/stop logs, not the actual logs): + - "tail" the logs: `journalctl --identifier daphne --follow` + - View the logs: `journalctl --identifier daphne --since "30 minutes ago" | less` + + === ":material-ubuntu: standard" + + - Service: `daphne.service` + - Socket: `/rmm/daphne.sock` + - Exec: `/rmm/api/env/bin/daphne -u /rmm/daphne.sock tacticalrmm.asgi:application` + - Config: `/rmm/api/tacticalrmm/tacticalrmm/local_settings.py` + - Log: `/rmm/api/tacticalrmm/tacticalrmm/private/log/debug.log` + + === ":material-docker: docker" + + TBD - To Be Documented + +#### NATS server service + +[NATS](https://nats.io/) is a messaging bus for "live" communication between the agent and server. NATS provides the framework for the server to push commands to the agent and receive information back. + +???+ note "systemd config" + + - [NATS server configuration docs](https://docs.nats.io/running-a-nats-service/configuration) + + === ":material-console-line: status commands" + + - Status: `systemctl status --full nats.service` + - Stop: `systemctl stop nats.service` + - Start: `systemctl start nats.service` + - Restart: `systemctl restart nats.service` + - Restart: `systemctl reload nats.service` reloads the config without restarting + - journalctl: + - "tail" the logs: `journalctl --identifier nats-server --follow` + - View the logs: `journalctl --identifier nats-server --since "30 minutes ago" | less` + - Listening process: `ss -tulnp | grep nats-server` + + === ":material-ubuntu: standard" + + - Service: `nats.service` + - Address: `0.0.0.0` + - Port: `4222` + - Exec: `/usr/local/bin/nats-server --config /rmm/api/tacticalrmm/nats-rmm.conf` + - Config: `/rmm/api/tacticalrmm/nats-rmm.conf` + - TLS: `/etc/letsencrypt/live/example.com/fullchain.pem` + - Log: None + - Version: v2.3.3 + + === ":material-docker: docker" + + TBD - To Be Documented + +#### NATS API service + +The NATS API service appears to bridge the connection between the NATS server and database, allowing the agent to save (i.e. push) information in the database. + +???+ note "systemd config" + + === ":material-console-line: status commands" + + - Status: `systemctl status --full nats-api.service` + - Stop: `systemctl stop nats-api.service` + - Start: `systemctl start nats-api.service` + - Restart: `systemctl restart nats-api.service` + - journalctl: This application does not appear to log anything. + + === ":material-ubuntu: standard" + + - Service: `nats-api.service` + - Exec: `/usr/local/bin/nats-server --config /rmm/api/tacticalrmm/nats-rmm.conf` + - Config: `/rmm/api/tacticalrmm/nats-rmm.conf` + - TLS: `/etc/letsencrypt/live/example.com/fullchain.pem` + - Log: None + + === ":material-docker: docker" + + TBD - To Be Documented + +#### Celery service + +[Celery](https://github.com/celery/celery) is a task queue focused on real-time processing and is responsible for scheduling tasks to be sent to agents. Log located at `/var/log/celery` -```bash -tail /var/log/celery -``` +???+ note "systemd config" -[Django](https://www.djangoproject.com/) + - [Celery docs](https://docs.celeryproject.org/en/stable/index.html) + - [Celery configuration docs](https://docs.celeryproject.org/en/stable/userguide/configuration.html) -!!!description - Framework to integrate the server to interact with browser + === ":material-console-line: status commands" + - Status: `systemctl status --full celery.service` + - Stop: `systemctl stop celery.service` + - Start: `systemctl start celery.service` + - Restart: `systemctl restart celery.service` + - journalctl: Celery executes `sh` causing the systemd identifier to be `sh`, thus mixing the `celery` and `celerybeat` logs together. + - "tail" the logs: `journalctl --identifier sh --follow` + - View the logs: `journalctl --identifier sh --since "30 minutes ago" | less` + - Tail logs: `tail -F /var/log/celery/w*-*.log` + + === ":material-ubuntu: standard" + + - Service: `celery.service` + - Exec: `/bin/sh -c '${CELERY_BIN} -A $CELERY_APP multi start $CELERYD_NODES --pidfile=${CELERYD_PID_FILE} --logfile=${CELERYD_LOG_FILE} --loglevel="${CELERYD_LOG_LEVEL}" $CELERYD_OPTS'` + - Config: `/etc/conf.d/celery.conf` + - Log: `/var/log/celery/w*-*.log` + + === ":material-docker: docker" + + TBD - To Be Documented + +#### Celery Beat service + +[celery beat](https://github.com/celery/django-celery-beat) is a scheduler; It kicks off tasks at regular intervals, that are then executed by available worker nodes in the cluster. + +???+ note "systemd config" + + - [Celery beat docs](https://docs.celeryproject.org/en/stable/userguide/periodic-tasks.html) + + === ":material-console-line: status commands" + + - Status: `systemctl status --full celerybeat.service` + - Stop: `systemctl stop celerybeat.service` + - Start: `systemctl start celerybeat.service` + - Restart: `systemctl restart celerybeat.service` + - journalctl: Celery executes `sh` causing the systemd identifier to be `sh`, thus mixing the `celery` and `celerybeat` logs together. + - "tail" the logs: `journalctl --identifier sh --follow` + - View the logs: `journalctl --identifier sh --since "30 minutes ago" | less` + - Tail logs: `tail -F /var/log/celery/beat.log` + + === ":material-ubuntu: standard" + + - Service: `celerybeat.service` + - Exec: `/bin/sh -c '${CELERY_BIN} -A ${CELERY_APP} beat --pidfile=${CELERYBEAT_PID_FILE} --logfile=${CELERYBEAT_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL}'` + - Config: `/etc/conf.d/celery.conf` + - Log: `/var/log/celery/beat.log` + + === ":material-docker: docker" + + TBD - To Be Documented + +### Dependencies + +[Django](https://www.djangoproject.com/) - Framework to integrate the server to interact with browser. + +
+ Django dependencies + +```text future==0.18.2 loguru==0.5.3 msgpack==1.0.2 @@ -60,28 +304,37 @@ pycryptodome==3.10.1 pyotp==2.6.0 pyparsing==2.4.7 pytz==2021.1 +``` +
-[qrcode](https://pypi.org/project/qrcode/) +[qrcode](https://pypi.org/project/qrcode/) - Creating QR codes for 2FA. -!!!description - For creating QR codes for 2FA +
+ qrcode dependencies +```text redis==3.5.3 requests==2.25.1 six==1.16.0 sqlparse==0.4.1 +``` +
-[twilio](https://www.twilio.com/) +[twilio](https://www.twilio.com/) - Python SMS notification integration. -!!!description - Python SMS notification integration +
+ twilio dependencies +```text urllib3==1.26.5 uWSGI==2.0.19.1 validators==0.18.2 vine==5.0.0 websockets==9.1 zipp==3.4.1 +``` +
+ ## Windows Agent @@ -101,7 +354,7 @@ Found in `%programfiles%\TacticalAgent` ![TacticalAgentServices](images/trmm_services.png) ![TacticalAgentTaskManager](images/trmm_services__taskmanager_agent.png) -The [MeshCentral](https://meshcentral.com/) system which is accessible from and is used +The [MeshCentral](https://meshcentral.com/) system which is accessible from `https://mesh.example.com` and is used * It runs 2 goroutines * one is the checkrunner which runs all the checks and then just sleeps until it's time to run more checks diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index cb9cfbc7c7..e18262aeab 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -74,16 +74,25 @@ theme: palette: primary: "white" accent: "indigo" + features: extra_css: - stylesheets/extra.css extra: social: - icon: fontawesome/brands/github link: "https://github.com/wh1te909/tacticalrmm" + markdown_extensions: - pymdownx.inlinehilite - admonition + - pymdownx.details - codehilite: guess_lang: false - toc: - permalink: true \ No newline at end of file + permalink: true + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true From cb388a5a78b909c9de63bb856845276926422b38 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Fri, 26 Nov 2021 14:35:33 -0500 Subject: [PATCH 28/48] scripts - adding demo server scripts --- .../scripts/community_scripts.json | 19 +++++++++++++++++++ scripts/Win_Printer_ClearandRestart.bat | 9 +++++++++ scripts/Win_Storage_CheckPools.ps1 | 16 ++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 scripts/Win_Printer_ClearandRestart.bat create mode 100644 scripts/Win_Storage_CheckPools.ps1 diff --git a/api/tacticalrmm/scripts/community_scripts.json b/api/tacticalrmm/scripts/community_scripts.json index 025254fcc8..930e11e167 100644 --- a/api/tacticalrmm/scripts/community_scripts.json +++ b/api/tacticalrmm/scripts/community_scripts.json @@ -9,6 +9,16 @@ "category": "TRMM (Win):Browsers", "default_timeout": "300" }, + { + "guid": "720edbb7-8faf-4a77-9283-29935e8880d0", + "filename": "Win_Printer_ClearandRestart.bat", + "submittedBy": "https://github.com/wh1te909", + "name": "Printers - Clear all print jobs", + "description": "This script will stop the spooler, delete all pending print jobs and restart the spooler", + "shell": "cmd", + "category": "TRMM (Win):Printing", + "default_timeout": "300" + }, { "guid": "3ff6a386-11d1-4f9d-8cca-1b0563bb6443", "filename": "Win_Google_Chrome_Clear_Cache.ps1", @@ -143,6 +153,15 @@ "shell": "powershell", "category": "TRMM (Win):Storage" }, + { + "guid": "11be7136-0416-47b4-a6dd-9776fa857dca", + "filename": "Win_Storage_CheckPools.ps1", + "submittedBy": "https://github.com/wh1te909", + "name": "Storage Pools - Check Health", + "description": "Checks all storage pools for health, returns error 1 if unhealthy", + "shell": "powershell", + "category": "TRMM (Win):Monitoring" + }, { "guid": "cfa14c28-4dfc-4d4e-95ee-a380652e058d", "filename": "Win_Bios_Check.ps1", diff --git a/scripts/Win_Printer_ClearandRestart.bat b/scripts/Win_Printer_ClearandRestart.bat new file mode 100644 index 0000000000..eff2008730 --- /dev/null +++ b/scripts/Win_Printer_ClearandRestart.bat @@ -0,0 +1,9 @@ +@echo off + +sc stop spooler + +timeout /t 5 /nobreak > NUL + +del C:\Windows\System32\spool\printers\* /Q /F /S + +sc start spooler \ No newline at end of file diff --git a/scripts/Win_Storage_CheckPools.ps1 b/scripts/Win_Storage_CheckPools.ps1 new file mode 100644 index 0000000000..00b8857a63 --- /dev/null +++ b/scripts/Win_Storage_CheckPools.ps1 @@ -0,0 +1,16 @@ +$pools = Get-VirtualDisk | select -ExpandProperty HealthStatus + +$err = $False + +ForEach ($pool in $pools) { + if ($pool -ne "Healthy") { + $err = $True + } +} + +if ($err) { + exit 1 +} +else { + exit 0 +} \ No newline at end of file From 8b2f9665ce05f37dcae31e4131ef77d9628becbd Mon Sep 17 00:00:00 2001 From: Hugo Sampaio Date: Fri, 26 Nov 2021 17:25:42 -0300 Subject: [PATCH 29/48] Update unsupported_scripts.md Added info about how I run rmm behind Apache Proxy ( discord Hugo ) --- docs/docs/unsupported_scripts.md | 63 ++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/docs/docs/unsupported_scripts.md b/docs/docs/unsupported_scripts.md index 8d81dc3031..c0dc0a5d56 100644 --- a/docs/docs/unsupported_scripts.md +++ b/docs/docs/unsupported_scripts.md @@ -869,3 +869,66 @@ Limit access to Tactical RMM's administration panel in nginx to specific locatio server_name rmm.example.com; return 404; } + + + + + +## Apache Proxy +howto - proxy on apache +### TRMM SERVER +edit file /etc/nginx/sites-available/rmm.conf +add the lines from 'real_ip' module inside server tag: + + + set_real_ip_from 192.168.0.200; #IP Address of your apache proxy + real_ip_header X-Forwarded-For; + +restart nginx + + systemctl restart nginx + +### APACHE +enable ssl proxy, rewriteEngine. +set proxy to preserve host. +set upgrade rule to websocket. +set proxypass rules redirecting to rmm location + +on your apache ssl config +example: + + + ServerName rmm.blablabla.com.br:443 + ServerAlias mesh.blablabla.com.br:443 api.blablabla.com.br:443 + SSLEngine on + + SSLCertificateFile "C:/Apache24/conf/ssl-rmm.blablabla.com.br/_.blablabla.com.br-chain.pem" + SSLCertificateKeyFile "C:/Apache24/conf/ssl-rmm.blablabla.com.br/_.blablabla.com.br-key.pem" + + SSLProxyEngine on + + RewriteEngine On + ProxyPreserveHost On + + # When Upgrade:websocket header is present, redirect to ws + # Using NC flag (case-insensitive) as some browsers will pass Websocket + RewriteCond %{HTTP:Upgrade} =websocket [NC] + RewriteRule ^/(.*) wss://192.168.0.212/$1 [P,L] + + ProxyPass "/" "https://192.168.0..212/" retry=3 + ProxyPassReverse "/" "https://192.168.0.212/" retry=3 + + BrowserMatch "MSIE [2-5]" \ + nokeepalive ssl-unclean-shutdown \ + downgrade-1.0 force-response-1.0 + + + + +### Updating certificate: +Im my case, auto DNS Challenge from apache, so every time we get new cert files, it must be copied inside rmm too. +just overwrite default location: +/etc/letsencrypt/archive/blablablabla +or change certs location on nginx conf to whatever you want. + + From 92ec1cc9e7628aac7cdd60b7470d13329a7cf110 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Fri, 26 Nov 2021 18:05:00 -0500 Subject: [PATCH 30/48] docs - add howitallworks to index --- docs/mkdocs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index cb9cfbc7c7..1f8c43f4d7 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -14,6 +14,7 @@ nav: - "Agent Installation": install_agent.md - "Updating Agents": update_agents.md - Functionality: + - "How it all Works": howitallworks.md - "Alerting": functions/alerting.md - "API Access": functions/api.md - "Automated Tasks": functions/automated_tasks.md From 4d5bddb4135bc43d06ddd4b13d7b91d5faec95ea Mon Sep 17 00:00:00 2001 From: sadnub Date: Sat, 27 Nov 2021 22:58:53 -0500 Subject: [PATCH 31/48] rework script form and add syntax field --- .../components/scripts/ScriptFormModal.vue | 150 +++++++++--------- 1 file changed, 76 insertions(+), 74 deletions(-) diff --git a/web/src/components/scripts/ScriptFormModal.vue b/web/src/components/scripts/ScriptFormModal.vue index 0e21ede9ee..24dbbae89d 100644 --- a/web/src/components/scripts/ScriptFormModal.vue +++ b/web/src/components/scripts/ScriptFormModal.vue @@ -1,6 +1,6 @@ @@ -177,11 +177,10 @@ export default { // script form logic const script = props.script - ? ref(Object.assign({}, props.script)) - : ref({ shell: "powershell", default_timeout: 90, args: [] }); + ? ref(Object.assign({}, { ...props.script, script_body: "" })) + : ref({ shell: "powershell", default_timeout: 90, args: [], script_body: "" }); if (props.clone) script.value.name = `(Copy) ${script.value.name}`; - const code = ref(""); const maximized = ref(false); const loading = ref(false); const agentLoading = ref(false); @@ -201,16 +200,13 @@ export default { // get code if editing or cloning script if (props.script) downloadScript(script.value.id, { with_snippets: props.readonly }).then(r => { - code.value = r.code; + script.value.script_body = r.code; }); async function submitForm() { loading.value = true; let result = ""; try { - // base64 encode the script text - script.value.code_base64 = btoa(code.value); - // edit existing script if (props.script && !props.clone) { result = await editScript(script.value); @@ -231,7 +227,7 @@ export default { $q.dialog({ component: TestScriptModal, componentProps: { - script: { ...script.value, code: code.value }, + script: { ...script.value }, agent: agent.value, }, }); @@ -247,7 +243,6 @@ export default { return { // reactive data formScript: script.value, - code, maximized, loading, agentOptions, diff --git a/web/src/components/scripts/ScriptUploadModal.vue b/web/src/components/scripts/ScriptUploadModal.vue index abb506b6fd..ce748a6258 100644 --- a/web/src/components/scripts/ScriptUploadModal.vue +++ b/web/src/components/scripts/ScriptUploadModal.vue @@ -118,12 +118,12 @@ export default { // base64 encode the script and delete file const reader = new FileReader(); reader.onloadend = () => { - script.value.code_base64 = reader.result.replace(/^data:.+;base64,/, ""); + script.value.script_body = reader.result; }; - reader.readAsDataURL(file.value); + reader.readAsText(file.value); } else { - script.value.code_base64 = ""; + script.value.script_body = ""; } }); From edf4815595dcce5820330a3abd77c7d0603abd00 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 28 Nov 2021 13:23:47 -0500 Subject: [PATCH 34/48] make script file encoding consistent. utf-8 --- scripts/Win_Defender_FullScan_Background.ps1 | 2 +- scripts/Win_Defender_QuickScan_Background.ps1 | 2 +- scripts/Win_Install_Adobe_Reader.ps1 | 2 +- scripts/Win_Start_Cleanup.ps1 | 2 +- scripts/Win_Windows_Update_Reset.ps1 | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/Win_Defender_FullScan_Background.ps1 b/scripts/Win_Defender_FullScan_Background.ps1 index af28671d88..909607cfb4 100644 --- a/scripts/Win_Defender_FullScan_Background.ps1 +++ b/scripts/Win_Defender_FullScan_Background.ps1 @@ -1,2 +1,2 @@ -Write-Host "Running Windows Defender Full Scan in Background" -ForegroundColor Green +Write-Host "Running Windows Defender Full Scan in Background" -ForegroundColor Green Start-MpScan -ScanPath C:\ -ScanType FullScan -AsJob \ No newline at end of file diff --git a/scripts/Win_Defender_QuickScan_Background.ps1 b/scripts/Win_Defender_QuickScan_Background.ps1 index 238220ad6e..497ec51fce 100644 --- a/scripts/Win_Defender_QuickScan_Background.ps1 +++ b/scripts/Win_Defender_QuickScan_Background.ps1 @@ -1,2 +1,2 @@ -Write-Host "Running Windows Defender Quick Scan in Background" -ForegroundColor Green +Write-Host "Running Windows Defender Quick Scan in Background" -ForegroundColor Green Start-MpScan -ScanType QuickScan -AsJob diff --git a/scripts/Win_Install_Adobe_Reader.ps1 b/scripts/Win_Install_Adobe_Reader.ps1 index 93d2a04da4..60927d646c 100644 --- a/scripts/Win_Install_Adobe_Reader.ps1 +++ b/scripts/Win_Install_Adobe_Reader.ps1 @@ -1,2 +1,2 @@ -#Install Adobe Reader DC +#Install Adobe Reader DC choco install adobereader -params '"/EnableUpdateService /UpdateMode:3 /DesktopIcon"' --yes --no-progress --force \ No newline at end of file diff --git a/scripts/Win_Start_Cleanup.ps1 b/scripts/Win_Start_Cleanup.ps1 index b99e430c02..506b76a768 100644 --- a/scripts/Win_Start_Cleanup.ps1 +++ b/scripts/Win_Start_Cleanup.ps1 @@ -1,4 +1,4 @@ -Function Start-Cleanup { +Function Start-Cleanup { <# .SYNOPSIS Automate cleaning up a C:\ drive with low disk space diff --git a/scripts/Win_Windows_Update_Reset.ps1 b/scripts/Win_Windows_Update_Reset.ps1 index 3b065a867e..6163e333cf 100644 --- a/scripts/Win_Windows_Update_Reset.ps1 +++ b/scripts/Win_Windows_Update_Reset.ps1 @@ -1,4 +1,4 @@ -<# +<# .SYNOPSIS Reset-WindowsUpdate.ps1 - Resets the Windows Update components From 1ee35da62dd0971cb22355587f4d763e2abe68a8 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Sun, 28 Nov 2021 15:31:37 -0500 Subject: [PATCH 35/48] docs updates --- docs/docs/contributing_using_docker.md | 6 +++++ docs/docs/howitallworks.md | 34 ++++++++++++++++++++++---- docs/docs/install_server.md | 2 +- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/docs/docs/contributing_using_docker.md b/docs/docs/contributing_using_docker.md index 0a3f4a5f12..25a3c88229 100644 --- a/docs/docs/contributing_using_docker.md +++ b/docs/docs/contributing_using_docker.md @@ -78,6 +78,12 @@ mkdocs is Exposed on Port: 8005 Open: [http://rmm.example.com:8005/](http://rmm.example.com:8005/) +!!!note + If you add new mkdocs extensions you might need to:
+ - docker-compose down.
+ - Then delete the `/api/tacticalrmm/env/` folder.
+ - Then docker-compose up and it will download/rebuild new extensions + ### View django administration Open: [http://rmm.example.com:8000/admin/](http://rmm.example.com:8000/admin/) diff --git a/docs/docs/howitallworks.md b/docs/docs/howitallworks.md index b99cd0291d..74f2628c00 100644 --- a/docs/docs/howitallworks.md +++ b/docs/docs/howitallworks.md @@ -1,10 +1,12 @@ # How It All Works -![Network Design](images/TacticalRMM-Network.png) +[![Network Design](images/TacticalRMM-Network.png)](images/TacticalRMM-Network.png) -1. Agent installer steps +Still need graphics for -2. Agent checks/tasks and how they work on the workstation/interact with server + 1. Agent installer steps + + 2. Agent checks/tasks and how they work on the workstation/interact with server ## Server @@ -15,7 +17,7 @@ Has a postgres database located here: !!!description A web interface for the postgres database -Dependencies from [here](https://github.com/wh1te909/tacticalrmm/blob/develop/api/tacticalrmm/requirements.txt) +All Tactical RMM dependencies are listed [here](https://github.com/wh1te909/tacticalrmm/blob/develop/api/tacticalrmm/requirements.txt) ### System Services @@ -286,7 +288,29 @@ Log located at `/var/log/celery` TBD - To Be Documented -### Dependencies +#### MeshCentral + +[MeshCentral](https://github.com/Ylianst/MeshCentral) is used for: "Take Control" (connecting to machine for remote access), and 2 screens of the "Remote Background" (Terminal, and File Browser). + +???+ note "meshcentral" + + - [MeshCentral docs](https://info.meshcentral.com/downloads/MeshCentral2/MeshCentral2UserGuide.pdf) + + === ":material-console-line: status commands" + + - Status: `systemctl status --full meshcentral` + - Stop: `systemctl stop meshcentral` + - Start: `systemctl start meshcentral` + - Restart: `systemctl restart meshcentral` + + === ":material-remote-desktop: Debugging" + + - Open either "Take Control" or "Remote Background" to get mesh login token + - Open https://mesh.example.com to open native mesh admin interface + - Left-side "My Server" > Choose "Console" > type `agentstats` + - To view detailed logging goto "Trace" > click Tracing button and choose categories + +### Other Dependencies [Django](https://www.djangoproject.com/) - Framework to integrate the server to interact with browser. diff --git a/docs/docs/install_server.md b/docs/docs/install_server.md index 7938e5a4b4..b6ab7782b7 100644 --- a/docs/docs/install_server.md +++ b/docs/docs/install_server.md @@ -186,7 +186,7 @@ If you have agents outside your local network: Make sure the public DNS servers Login to your router/NAT device. -1. Set your TRMM server as a static IP (Use a DHCP reservation is usually safer) +1. Set your TRMM server as a static IP (Using a DHCP reservation is usually safer) 2. Create 2 port forwarding rules. `TCP Port 443` and `TCP Port 4222` to your TRMM servers private IP address. !!!note From 31462cab6423126543de997a543ceea1bcdb4012 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 28 Nov 2021 20:59:21 -0500 Subject: [PATCH 36/48] fix tests and also check for the correct script hash --- api/tacticalrmm/scripts/models.py | 1 - api/tacticalrmm/scripts/tests.py | 43 +++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/api/tacticalrmm/scripts/models.py b/api/tacticalrmm/scripts/models.py index e6a665f57e..82fa0c751d 100644 --- a/api/tacticalrmm/scripts/models.py +++ b/api/tacticalrmm/scripts/models.py @@ -1,4 +1,3 @@ -import base64 import re import hmac import hashlib diff --git a/api/tacticalrmm/scripts/tests.py b/api/tacticalrmm/scripts/tests.py index 39305cab67..75a6c7a73d 100644 --- a/api/tacticalrmm/scripts/tests.py +++ b/api/tacticalrmm/scripts/tests.py @@ -1,8 +1,12 @@ import json import os +import hmac +import hashlib + from pathlib import Path from unittest.mock import patch +from django.test import override_settings from django.conf import settings from model_bakery import baker from tacticalrmm.test import TacticalTestCase @@ -31,6 +35,9 @@ def test_get_scripts(self): self.check_not_authenticated("get", url) + @override_settings( + SECRET_KEY="Test Secret Key" + ) def test_add_script(self): url = f"/scripts/" @@ -39,7 +46,7 @@ def test_add_script(self): "description": "Description", "shell": "powershell", "category": "New", - "code_base64": "VGVzdA==", # Test + "script_body": "Test Script", "default_timeout": 99, "args": ["hello", "world", r"{{agent.public_ip}}"], "favorite": False, @@ -48,11 +55,18 @@ def test_add_script(self): # test without file upload resp = self.client.post(url, data, format="json") self.assertEqual(resp.status_code, 200) - self.assertTrue(Script.objects.filter(name="Name").exists()) - self.assertEqual(Script.objects.get(name="Name").code, "Test") + + new_script = Script.objects.filter(name="Name").get() + self.assertTrue(new_script) + + correct_hash = hmac.new(settings.SECRET_KEY.encode(), data["script_body"].encode(), hashlib.sha256).hexdigest() + self.assertEqual(new_script.script_hash, correct_hash) self.check_not_authenticated("post", url) + @override_settings( + SECRET_KEY="Test Secret Key" + ) def test_modify_script(self): # test a call where script doesn't exist resp = self.client.put("/scripts/500/", format="json") @@ -66,7 +80,7 @@ def test_modify_script(self): "name": script.name, "description": "Description Change", "shell": script.shell, - "code_base64": "VGVzdA==", # Test + "script_body": "Test Script Body", # Test "default_timeout": 13344556, } @@ -75,14 +89,15 @@ def test_modify_script(self): self.assertEqual(resp.status_code, 200) script = Script.objects.get(pk=script.pk) self.assertEquals(script.description, "Description Change") - self.assertEquals(script.code, "Test") - # test edit a builtin script + correct_hash = hmac.new(settings.SECRET_KEY.encode(), data["script_body"].encode(), hashlib.sha256).hexdigest() + self.assertEqual(script.script_hash, correct_hash) + # test edit a builtin script data = { "name": "New Name", "description": "New Desc", - "code_base64": "VGVzdA==", + "script_body": "aasdfdsf", } # Test builtin_script = baker.make_recipe("scripts.script", script_type="builtin") @@ -94,7 +109,7 @@ def test_modify_script(self): "description": "Description Change", "shell": script.shell, "favorite": True, - "code_base64": "VGVzdA==", # Test + "script_body": "Test Script Body", # Test "default_timeout": 54345, } # test marking a builtin script as favorite @@ -166,29 +181,29 @@ def test_download_script(self): # test powershell file script = baker.make( - "scripts.Script", code_base64="VGVzdA==", shell="powershell" + "scripts.Script", script_body="Test Script Body", shell="powershell" ) url = f"/scripts/{script.pk}/download/" # type: ignore resp = self.client.get(url, format="json") self.assertEqual(resp.status_code, 200) - self.assertEqual(resp.data, {"filename": f"{script.name}.ps1", "code": "Test"}) # type: ignore + self.assertEqual(resp.data, {"filename": f"{script.name}.ps1", "code": "Test Script Body"}) # type: ignore # test batch file - script = baker.make("scripts.Script", code_base64="VGVzdA==", shell="cmd") + script = baker.make("scripts.Script", script_body="Test Script Body", shell="cmd") url = f"/scripts/{script.pk}/download/" # type: ignore resp = self.client.get(url, format="json") self.assertEqual(resp.status_code, 200) - self.assertEqual(resp.data, {"filename": f"{script.name}.bat", "code": "Test"}) # type: ignore + self.assertEqual(resp.data, {"filename": f"{script.name}.bat", "code": "Test Script Body"}) # type: ignore # test python file - script = baker.make("scripts.Script", code_base64="VGVzdA==", shell="python") + script = baker.make("scripts.Script", script_body="Test Script Body", shell="python") url = f"/scripts/{script.pk}/download/" # type: ignore resp = self.client.get(url, format="json") self.assertEqual(resp.status_code, 200) - self.assertEqual(resp.data, {"filename": f"{script.name}.py", "code": "Test"}) # type: ignore + self.assertEqual(resp.data, {"filename": f"{script.name}.py", "code": "Test Script Body"}) # type: ignore self.check_not_authenticated("get", url) From 911b6bf863fab025854c39896252e7399a020ba3 Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 28 Nov 2021 21:07:09 -0500 Subject: [PATCH 37/48] fix sorting process cpu percentage. Fixes #831 --- web/src/components/agents/remotebg/ProcessManager.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/agents/remotebg/ProcessManager.vue b/web/src/components/agents/remotebg/ProcessManager.vue index efcf61d9cd..8333467355 100644 --- a/web/src/components/agents/remotebg/ProcessManager.vue +++ b/web/src/components/agents/remotebg/ProcessManager.vue @@ -95,7 +95,7 @@ const columns = [ field: "cpu_percent", align: "left", sortable: true, - sort: (a, b, rowA, rowB) => parseInt(b) < parseInt(a), + sort: (a, b, rowA, rowB) => parseFloat(b) < parseFloat(a), }, { name: "membytes", From 2c2cbaa1757f3573a3f85e233275c4e37f3ca2ff Mon Sep 17 00:00:00 2001 From: sadnub Date: Sun, 28 Nov 2021 21:08:41 -0500 Subject: [PATCH 38/48] formatting --- .../management/commands/post_update_tasks.py | 12 ++++---- api/tacticalrmm/scripts/models.py | 18 ++++++------ api/tacticalrmm/scripts/serializers.py | 1 + api/tacticalrmm/scripts/tests.py | 28 +++++++++++-------- 4 files changed, 34 insertions(+), 25 deletions(-) diff --git a/api/tacticalrmm/core/management/commands/post_update_tasks.py b/api/tacticalrmm/core/management/commands/post_update_tasks.py index bbbbfa15a3..75ab387aee 100644 --- a/api/tacticalrmm/core/management/commands/post_update_tasks.py +++ b/api/tacticalrmm/core/management/commands/post_update_tasks.py @@ -23,10 +23,12 @@ def handle(self, *args, **kwargs): user.save() # convert script base64 field to text field - user_scripts = Script.objects.exclude(script_type="builtin").filter(script_body="") + user_scripts = Script.objects.exclude(script_type="builtin").filter( + script_body="" + ) for script in user_scripts: # decode base64 string - script.script_body = base64.b64decode(script.code_base64.encode("ascii", "ignore")).decode( - "ascii", "ignore" - ) - script.hash_script_body() # also saves script + script.script_body = base64.b64decode( + script.code_base64.encode("ascii", "ignore") + ).decode("ascii", "ignore") + script.hash_script_body() # also saves script diff --git a/api/tacticalrmm/scripts/models.py b/api/tacticalrmm/scripts/models.py index 82fa0c751d..a6c3c01e65 100644 --- a/api/tacticalrmm/scripts/models.py +++ b/api/tacticalrmm/scripts/models.py @@ -43,7 +43,7 @@ class Script(BaseAuditModel): category = models.CharField(max_length=100, null=True, blank=True) script_body = models.TextField(blank=True, default="") script_hash = models.CharField(max_length=100, null=True, blank=True) - code_base64 = models.TextField(blank=True, default="") # deprecated + code_base64 = models.TextField(blank=True, default="") # deprecated default_timeout = models.PositiveIntegerField(default=90) def __str__(self): @@ -80,7 +80,9 @@ def hash_script_body(self): from django.conf import settings msg = self.code.encode() - self.script_hash = hmac.new(settings.SECRET_KEY.encode(), msg, hashlib.sha256).hexdigest() + self.script_hash = hmac.new( + settings.SECRET_KEY.encode(), msg, hashlib.sha256 + ).hexdigest() self.save() @classmethod @@ -135,8 +137,8 @@ def load_community_scripts(cls): i.filename = script["filename"] # type: ignore with open(os.path.join(scripts_dir, script["filename"]), "rb") as f: - i.script_body = f.read().decode('utf-8') # type: ignore - i.hash_script_body() # also saves script + i.script_body = f.read().decode("utf-8") # type: ignore + i.hash_script_body() # also saves script # check if script was added without a guid elif cls.objects.filter( @@ -159,14 +161,14 @@ def load_community_scripts(cls): with open( os.path.join(scripts_dir, script["filename"]), "rb" ) as f: - s.script_body = f.read().decode('utf-8') - s.hash_script_body() # also saves the script + s.script_body = f.read().decode("utf-8") + s.hash_script_body() # also saves the script else: print(f"Adding new community script: {script['name']}") with open(os.path.join(scripts_dir, script["filename"]), "rb") as f: - script_body = f.read().decode('utf-8') + script_body = f.read().decode("utf-8") new_script = cls( script_body=script_body, @@ -181,7 +183,7 @@ def load_community_scripts(cls): filename=script["filename"], syntax=syntax, ) - new_script.hash_script_body() # also saves script + new_script.hash_script_body() # also saves script # delete community scripts that had their name changed cls.objects.filter(script_type="builtin", guid=None).delete() diff --git a/api/tacticalrmm/scripts/serializers.py b/api/tacticalrmm/scripts/serializers.py index 4ae9472868..9875cb44a0 100644 --- a/api/tacticalrmm/scripts/serializers.py +++ b/api/tacticalrmm/scripts/serializers.py @@ -23,6 +23,7 @@ class Meta: class ScriptSerializer(ModelSerializer): script_hash = ReadOnlyField() + class Meta: model = Script fields = [ diff --git a/api/tacticalrmm/scripts/tests.py b/api/tacticalrmm/scripts/tests.py index 75a6c7a73d..787897e9dd 100644 --- a/api/tacticalrmm/scripts/tests.py +++ b/api/tacticalrmm/scripts/tests.py @@ -35,9 +35,7 @@ def test_get_scripts(self): self.check_not_authenticated("get", url) - @override_settings( - SECRET_KEY="Test Secret Key" - ) + @override_settings(SECRET_KEY="Test Secret Key") def test_add_script(self): url = f"/scripts/" @@ -46,7 +44,7 @@ def test_add_script(self): "description": "Description", "shell": "powershell", "category": "New", - "script_body": "Test Script", + "script_body": "Test Script", "default_timeout": 99, "args": ["hello", "world", r"{{agent.public_ip}}"], "favorite": False, @@ -58,15 +56,15 @@ def test_add_script(self): new_script = Script.objects.filter(name="Name").get() self.assertTrue(new_script) - - correct_hash = hmac.new(settings.SECRET_KEY.encode(), data["script_body"].encode(), hashlib.sha256).hexdigest() + + correct_hash = hmac.new( + settings.SECRET_KEY.encode(), data["script_body"].encode(), hashlib.sha256 + ).hexdigest() self.assertEqual(new_script.script_hash, correct_hash) self.check_not_authenticated("post", url) - @override_settings( - SECRET_KEY="Test Secret Key" - ) + @override_settings(SECRET_KEY="Test Secret Key") def test_modify_script(self): # test a call where script doesn't exist resp = self.client.put("/scripts/500/", format="json") @@ -90,7 +88,9 @@ def test_modify_script(self): script = Script.objects.get(pk=script.pk) self.assertEquals(script.description, "Description Change") - correct_hash = hmac.new(settings.SECRET_KEY.encode(), data["script_body"].encode(), hashlib.sha256).hexdigest() + correct_hash = hmac.new( + settings.SECRET_KEY.encode(), data["script_body"].encode(), hashlib.sha256 + ).hexdigest() self.assertEqual(script.script_hash, correct_hash) # test edit a builtin script @@ -190,7 +190,9 @@ def test_download_script(self): self.assertEqual(resp.data, {"filename": f"{script.name}.ps1", "code": "Test Script Body"}) # type: ignore # test batch file - script = baker.make("scripts.Script", script_body="Test Script Body", shell="cmd") + script = baker.make( + "scripts.Script", script_body="Test Script Body", shell="cmd" + ) url = f"/scripts/{script.pk}/download/" # type: ignore resp = self.client.get(url, format="json") @@ -198,7 +200,9 @@ def test_download_script(self): self.assertEqual(resp.data, {"filename": f"{script.name}.bat", "code": "Test Script Body"}) # type: ignore # test python file - script = baker.make("scripts.Script", script_body="Test Script Body", shell="python") + script = baker.make( + "scripts.Script", script_body="Test Script Body", shell="python" + ) url = f"/scripts/{script.pk}/download/" # type: ignore resp = self.client.get(url, format="json") From 3f3ab088d233734db0375681dd66fba2ed518154 Mon Sep 17 00:00:00 2001 From: silversword411 Date: Mon, 29 Nov 2021 09:47:38 -0500 Subject: [PATCH 39/48] docs - adding bulk delete --- docs/docs/management_cmds.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/docs/management_cmds.md b/docs/docs/management_cmds.md index 11b11fd270..59a3b3dac4 100644 --- a/docs/docs/management_cmds.md +++ b/docs/docs/management_cmds.md @@ -7,6 +7,22 @@ cd /rmm/api/tacticalrmm source ../env/bin/activate ``` +## Bulk Delete old agents by last checkin date or agent version + +Test to see what will happen + +```bash +python manage.py bulk_delete_agents --days 60 +python manage.py bulk_delete_agents --agentver 1.5.0 +``` + +Do the delete + +```bash +python manage.py bulk_delete_agents --days 60 --delete +python manage.py bulk_delete_agents --agentver 1.5.0 --delete +``` + ## Reset a user's password ```bash From f38cfdcadfdc46e1c1f8a6256dd038d606d2efae Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Mon, 29 Nov 2021 18:51:18 +0000 Subject: [PATCH 40/48] fix test script --- web/src/components/scripts/TestScriptModal.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/components/scripts/TestScriptModal.vue b/web/src/components/scripts/TestScriptModal.vue index 7976c2095d..d49eb18c07 100644 --- a/web/src/components/scripts/TestScriptModal.vue +++ b/web/src/components/scripts/TestScriptModal.vue @@ -46,7 +46,7 @@ export default { async function runTestScript() { loading.value = true; const data = { - code: props.script.code, + code: props.script.script_body, timeout: props.script.default_timeout, args: props.script.args, shell: props.script.shell, From 54d3177fdd2ab125acbb3fc316e9bf7f4c7e3138 Mon Sep 17 00:00:00 2001 From: sadnub Date: Mon, 29 Nov 2021 17:19:34 -0500 Subject: [PATCH 41/48] also don't include callable attributes with variable substitutions on alert scripts --- api/tacticalrmm/alerts/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/tacticalrmm/alerts/models.py b/api/tacticalrmm/alerts/models.py index 50f386cbee..cdaf2b53e6 100644 --- a/api/tacticalrmm/alerts/models.py +++ b/api/tacticalrmm/alerts/models.py @@ -456,7 +456,8 @@ def parse_script_args(self, args: list[str]): if match: name = match.group(1) - if hasattr(self, name): + # check if attr exists and isn't a function + if hasattr(self, name) and not callable(getattr(self, name)): value = f"'{getattr(self, name)}'" else: continue From 1c80f6f3fa2174eb7d7515a2c663785b62f33b53 Mon Sep 17 00:00:00 2001 From: sadnub Date: Mon, 29 Nov 2021 22:18:05 -0500 Subject: [PATCH 42/48] Don't allow script arg variable assignment to callable attributes. Fixes #726 --- api/tacticalrmm/tacticalrmm/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/tacticalrmm/tacticalrmm/utils.py b/api/tacticalrmm/tacticalrmm/utils.py index e57b533af2..301e095727 100644 --- a/api/tacticalrmm/tacticalrmm/utils.py +++ b/api/tacticalrmm/tacticalrmm/utils.py @@ -299,7 +299,8 @@ def replace_db_values( if not obj: return "" - if hasattr(obj, temp[1]): + # check if attr exists and isn't a function + if hasattr(obj, temp[1]) and not callable(getattr(obj, temp[1])): value = f"'{getattr(obj, temp[1])}'" if quotes else getattr(obj, temp[1]) elif CustomField.objects.filter(model=model, name=temp[1]).exists(): From 6fe1dccc7e4ac748982e4163687c6d186501a3aa Mon Sep 17 00:00:00 2001 From: silversword411 Date: Tue, 30 Nov 2021 18:15:49 -0500 Subject: [PATCH 43/48] docs outbound firewall rules --- docs/docs/howitallworks.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/docs/howitallworks.md b/docs/docs/howitallworks.md index 74f2628c00..ec5e2b03a9 100644 --- a/docs/docs/howitallworks.md +++ b/docs/docs/howitallworks.md @@ -364,6 +364,20 @@ zipp==3.4.1 Found in `%programfiles%\TacticalAgent` +### Outbound Firewall Rules + +#### Unsigned Agents + +Unsigned agents require: https://github.com/wh1te909/rmmagent/releases/* + +The agent uses this to obtain public IP info: `curl https://icanhazip.tacticalrmm.io/` + +#### Signed Agents + +The agent uses this to obtain public IP info: `curl https://icanhazip.tacticalrmm.io/` + +Signed agents would require: https://exe.tacticalrmm.io/ and https://exe2.tacticalrmm.io/ for downloading/updating agents + ### Services 3 services exist on all clients From 9b001219d5636465051e480f4ee5f3c01f6c0a1a Mon Sep 17 00:00:00 2001 From: silversword411 Date: Wed, 1 Dec 2021 12:27:52 -0500 Subject: [PATCH 44/48] docs tweak --- docs/docs/howitallworks.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/docs/howitallworks.md b/docs/docs/howitallworks.md index ec5e2b03a9..129804eb6e 100644 --- a/docs/docs/howitallworks.md +++ b/docs/docs/howitallworks.md @@ -366,17 +366,19 @@ Found in `%programfiles%\TacticalAgent` ### Outbound Firewall Rules -#### Unsigned Agents +If you have strict firewall rules these are the only outbound rules from the agent needed for all functionality: -Unsigned agents require: https://github.com/wh1te909/rmmagent/releases/* +1. All agents have to be able to connect outbound to TRMM server on the 3 domain names on ports: 443 (agent and mesh) and 4222 (nats for checks/tasks/data) -The agent uses this to obtain public IP info: `curl https://icanhazip.tacticalrmm.io/` +2. The agent uses this to obtain public IP info: `curl https://icanhazip.tacticalrmm.io/` -#### Signed Agents +#### Unsigned Agents -The agent uses this to obtain public IP info: `curl https://icanhazip.tacticalrmm.io/` +Unsigned agents require access to: https://github.com/wh1te909/rmmagent/releases/* + +#### Signed Agents -Signed agents would require: https://exe.tacticalrmm.io/ and https://exe2.tacticalrmm.io/ for downloading/updating agents +Signed agents will require: https://exe.tacticalrmm.io/ and https://exe2.tacticalrmm.io/ for downloading/updating agents ### Services From 0237b48c870edacf6520c2b6f3289722b704cec8 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Wed, 1 Dec 2021 19:37:53 +0000 Subject: [PATCH 45/48] update reqs --- api/tacticalrmm/requirements.txt | 4 +- api/tacticalrmm/tacticalrmm/settings.py | 2 +- web/package-lock.json | 1143 ++++++++++++++--------- web/package.json | 6 +- 4 files changed, 726 insertions(+), 429 deletions(-) diff --git a/api/tacticalrmm/requirements.txt b/api/tacticalrmm/requirements.txt index 4387e74b9d..00945741fd 100644 --- a/api/tacticalrmm/requirements.txt +++ b/api/tacticalrmm/requirements.txt @@ -1,5 +1,5 @@ asgiref==3.4.1 -asyncio-nats-client==0.11.4 +asyncio-nats-client==0.11.5 celery==5.2.1 certifi==2021.10.8 cffi==1.15.0 @@ -15,7 +15,7 @@ django-rest-knox==4.1.0 djangorestframework==3.12.4 future==0.18.2 loguru==0.5.3 -msgpack==1.0.2 +msgpack==1.0.3 packaging==21.3 psycopg2-binary==2.9.2 pycparser==2.21 diff --git a/api/tacticalrmm/tacticalrmm/settings.py b/api/tacticalrmm/tacticalrmm/settings.py index a4f97a3ae0..e9ccf3e5d2 100644 --- a/api/tacticalrmm/tacticalrmm/settings.py +++ b/api/tacticalrmm/tacticalrmm/settings.py @@ -32,7 +32,7 @@ PIP_VER = "24" NPM_VER = "25" -SETUPTOOLS_VER = "58.5.3" +SETUPTOOLS_VER = "59.4.0" WHEEL_VER = "0.37.0" DL_64 = f"https://github.com/wh1te909/rmmagent/releases/download/v{LATEST_AGENT_VER}/winagent-v{LATEST_AGENT_VER}.exe" diff --git a/web/package-lock.json b/web/package-lock.json index d276775a9f..1a8c9d788b 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,18 +8,18 @@ "name": "web", "version": "0.1.8", "dependencies": { - "@quasar/extras": "^1.12.0", + "@quasar/extras": "^1.12.1", "apexcharts": "^3.27.1", "axios": "^0.24.0", "dotenv": "^8.6.0", "qrcode.vue": "^3.2.2", - "quasar": "^2.3.2", + "quasar": "^2.3.3", "vue3-ace-editor": "^2.2.1", "vue3-apexcharts": "^1.4.0", "vuex": "^4.0.2" }, "devDependencies": { - "@quasar/app": "^3.2.3", + "@quasar/app": "^3.2.4", "@quasar/cli": "^1.2.2" } }, @@ -1846,9 +1846,9 @@ } }, "node_modules/@quasar/app": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@quasar/app/-/app-3.2.3.tgz", - "integrity": "sha512-bHANWxtN2IOYhfKRGNadfGuP5NHuAIcvCgS8MVxGU/LMEwBZX8Q7YwYYid2z7gO9G0pCd2d3RH9aQ1IFMeWGRA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@quasar/app/-/app-3.2.4.tgz", + "integrity": "sha512-iiQDnKs/t+qCFxNHSi2knhsIzS34jVLwfI4FbFwZLDyOEmocEXp7h4Y8nAxTLPxQBM2zUc/Xv1QBvmw0t0iS7A==", "dev": true, "dependencies": { "@quasar/babel-preset-app": "2.0.1", @@ -1858,19 +1858,19 @@ "@types/cordova": "0.0.34", "@types/express": "4.17.13", "@types/webpack-bundle-analyzer": "4.4.1", - "@types/webpack-dev-server": "4.3.1", + "@types/webpack-dev-server": "4.5.0", "archiver": "5.3.0", "autoprefixer": "10.4.0", "browserslist": "^4.12.0", "chalk": "4.1.2", "chokidar": "3.5.2", - "ci-info": "3.2.0", - "compression-webpack-plugin": "9.0.0", + "ci-info": "3.3.0", + "compression-webpack-plugin": "9.0.1", "copy-webpack-plugin": "9.1.0", "cross-spawn": "7.0.3", "css-loader": "5.2.6", - "css-minimizer-webpack-plugin": "3.1.3", - "cssnano": "5.0.10", + "css-minimizer-webpack-plugin": "3.2.0", + "cssnano": "5.0.12", "dot-prop": "6.0.1", "elementtree": "0.1.7", "error-stack-parser": "2.0.6", @@ -1897,8 +1897,8 @@ "open": "7.1.0", "ouch": "2.0.0", "postcss": "^8.2.10", - "postcss-loader": "6.2.0", - "postcss-rtlcss": "3.4.1", + "postcss-loader": "6.2.1", + "postcss-rtlcss": "3.5.0", "pretty-error": "4.0.0", "register-service-worker": "1.7.2", "sass": "1.32.12", @@ -1909,14 +1909,14 @@ "ts-loader": "9.2.5", "typescript": "4.4.2", "url-loader": "4.1.1", - "vue": "3.2.22", + "vue": "3.2.23", "vue-loader": "16.8.3", "vue-router": "4.0.12", "vue-style-loader": "4.1.3", "webpack": "^5.58.1", "webpack-bundle-analyzer": "4.5.0", "webpack-chain": "6.5.1", - "webpack-dev-server": "4.4.0", + "webpack-dev-server": "4.6.0", "webpack-merge": "5.8.0", "webpack-node-externals": "3.0.0" }, @@ -1945,6 +1945,12 @@ } } }, + "node_modules/@quasar/app/node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, "node_modules/@quasar/babel-preset-app": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@quasar/babel-preset-app/-/babel-preset-app-2.0.1.tgz", @@ -2070,9 +2076,9 @@ } }, "node_modules/@quasar/extras": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.12.0.tgz", - "integrity": "sha512-X4oBMf5xcwk8+z2SrVU3AJ2dbFWZ4+LkjZCcXf4sgfY652CatzX+uaZl5UJtQEnl62PwwFTSPXPGy8t0uWF3sA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.12.1.tgz", + "integrity": "sha512-EwOnaJEDHo9zCnJzd1sFw1sfMAAq8cJaIjzr2+A9o2NcVLaIhD7YAaJdlIdcNmQnyuPAiq9NghUize8lCS0epw==", "funding": { "type": "github", "url": "https://donate.quasar.dev" @@ -2131,9 +2137,9 @@ } }, "node_modules/@types/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "dev": true, "dependencies": { "@types/connect": "*", @@ -2184,6 +2190,47 @@ "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=", "dev": true }, + "node_modules/@types/cssnano": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/cssnano/-/cssnano-4.0.1.tgz", + "integrity": "sha512-hGOroxRTBkYl5gSBRJOffhV4+io+Y2bFX1VP7LgKEVHJt/LPPJaWUIuDAz74Vlp7l7hCDZfaDi7iPxwNwuVA4Q==", + "dev": true, + "dependencies": { + "postcss": "5 - 7" + } + }, + "node_modules/@types/cssnano/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/@types/cssnano/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/@types/cssnano/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@types/eslint": { "version": "7.28.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz", @@ -2223,9 +2270,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", - "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", + "version": "4.17.26", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.26.tgz", + "integrity": "sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ==", "dev": true, "dependencies": { "@types/node": "*", @@ -2338,9 +2385,9 @@ } }, "node_modules/@types/webpack-dev-server": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz", - "integrity": "sha512-sFAFnvz1Ah17Kt4pFjATbPtuAmFS9s2dUUKhpz0kkB+X7vpJF2tbO7JoHP42od0SKijtrB7CHbsa3/lnztjpvw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-4.5.0.tgz", + "integrity": "sha512-HMb6pZPANObue3LwbdpQLWzQyF9O0wntiPyXj4vGutlAbNKTXH4hDCHaZyfvfZDmFn+5HprrWHm1TGt3awNr/A==", "dev": true, "dependencies": { "@types/bonjour": "*", @@ -2355,12 +2402,12 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.22.tgz", - "integrity": "sha512-uAkovrVeTcjzpiM4ECmVaMrv/bjdgAaLzvjcGqQPBEyUrcqsCgccT9fHJ/+hWVGhyMahmBwLqcn4guULNx7sdw==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.23.tgz", + "integrity": "sha512-4ZhiI/orx+7EJ1B+0zjgvXMV2uRN+XBfG06UN2sJfND9rH5gtEQT3QmO4erum1o6Irl7y754W8/KSaDJh4EUQg==", "dependencies": { "@babel/parser": "^7.15.0", - "@vue/shared": "3.2.22", + "@vue/shared": "3.2.23", "estree-walker": "^2.0.2", "source-map": "^0.6.1" } @@ -2374,25 +2421,25 @@ } }, "node_modules/@vue/compiler-dom": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.22.tgz", - "integrity": "sha512-VZdsw/VuO1ODs8K7NQwnMQzKITDkIFlYYC03SVnunuf6eNRxBPEonSyqbWNoo6qNaHAEBTG6VVcZC5xC9bAx1g==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.23.tgz", + "integrity": "sha512-X2Nw8QFc5lgoK3kio5ktM95nqmLUH+q+N/PbV4kCHzF1avqv/EGLnAhaaF0Iu4bewNvHJAAhhwPZFeoV/22nbw==", "dependencies": { - "@vue/compiler-core": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/compiler-core": "3.2.23", + "@vue/shared": "3.2.23" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.22.tgz", - "integrity": "sha512-tWRQ5ge1tsTDhUwHgueicKJ8rYm6WUVAPTaIpFW3GSwZKcOEJ2rXdfkHFShNVGupeRALz2ET2H84OL0GeRxY0A==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.23.tgz", + "integrity": "sha512-Aw+pb50Q5zTjyvWod8mNKmYZDRGHJBptmNNWE+84ZxrzEztPgMz8cNYIzWGbwcFVkmJlhvioAMvKnB+LM/sjSA==", "dependencies": { "@babel/parser": "^7.15.0", - "@vue/compiler-core": "3.2.22", - "@vue/compiler-dom": "3.2.22", - "@vue/compiler-ssr": "3.2.22", - "@vue/ref-transform": "3.2.22", - "@vue/shared": "3.2.22", + "@vue/compiler-core": "3.2.23", + "@vue/compiler-dom": "3.2.23", + "@vue/compiler-ssr": "3.2.23", + "@vue/ref-transform": "3.2.23", + "@vue/shared": "3.2.23", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -2408,12 +2455,12 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.22.tgz", - "integrity": "sha512-Cl6aoLJtXzzBkk1sKod8S0WBJLts3+ugVC91d22gGpbkw/64WnF12tOZi7Rg54PPLi1NovqyNWPsLH/SAFcu+w==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.23.tgz", + "integrity": "sha512-Bqzn4jFyXPK1Ehqiq7e/czS8n62gtYF1Zfeu0DrR5uv+SBllh7LIvZjZU6+c8qbocAd3/T3I3gn2cZGmnDb6zg==", "dependencies": { - "@vue/compiler-dom": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/compiler-dom": "3.2.23", + "@vue/shared": "3.2.23" } }, "node_modules/@vue/devtools-api": { @@ -2422,60 +2469,60 @@ "integrity": "sha512-21u2jFOk8jbAneeGpDwZQ0W66RJa0IBDUyVl6SgKnn2cRFjLWzKj+ukXjpLhYr1KASyCe5E5U4jXwChVo0YUAw==" }, "node_modules/@vue/reactivity": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.22.tgz", - "integrity": "sha512-xNkLAItjI0xB+lFeDgKCrSItmrHTaAzSnt8LmdSCPQnDyarmzbi/u4ESQnckWvlL7lSRKiEaOvblaNyqAa7OnQ==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.23.tgz", + "integrity": "sha512-8RGVr/5Kpgb/EkCjgHXqttgA5IMc6n0lIXFY4TVbMkzdXrvaIhzBd7Te44oIDsTSYVKZLpfHd6/wEnuDqE8vFw==", "dependencies": { - "@vue/shared": "3.2.22" + "@vue/shared": "3.2.23" } }, "node_modules/@vue/ref-transform": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.22.tgz", - "integrity": "sha512-qalVWbq5xWWxLZ0L9OroBg/JZhzavQuCcDXblfErxyDEH6Xc5gIJ4feo1SVCICFzhAUgLgQTdSFLpgjBawbFpw==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.23.tgz", + "integrity": "sha512-gW0GD2PSAs/th7mC7tPB/UwpIQxclbApVtsDtscDmOJXb2+cdu60ny+SuHNgfrlUT/JqWKQHq7jFKO4woxLNaA==", "dependencies": { "@babel/parser": "^7.15.0", - "@vue/compiler-core": "3.2.22", - "@vue/shared": "3.2.22", + "@vue/compiler-core": "3.2.23", + "@vue/shared": "3.2.23", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "node_modules/@vue/runtime-core": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.22.tgz", - "integrity": "sha512-e7WOC55wmHPvmoVUk9VBe/Z9k5bJfWJfVIlkUkiADJn0bOgQD29oh/GS14Kb3aEJXIHLI17Em6+HxNut1sIh7Q==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.23.tgz", + "integrity": "sha512-wSI5lmY2kCGLf89iiygqxVh6/5bsawz78Me9n1x4U2bHnN0yf3PWyuhN0WgIE8VfEaF7e75E333uboNEIFjgkg==", "dependencies": { - "@vue/reactivity": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/reactivity": "3.2.23", + "@vue/shared": "3.2.23" } }, "node_modules/@vue/runtime-dom": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.22.tgz", - "integrity": "sha512-w7VHYJoliLRTLc5beN77wxuOjla4v9wr2FF22xpZFYBmH4U1V7HkYhoHc1BTuNghI15CXT1tNIMhibI1nrQgdw==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.23.tgz", + "integrity": "sha512-z6lp0888NkLmxD9j2sGoll8Kb7J743s8s6w7GbiyUc4WZwm0KJ35B4qTFDMoIU0G7CatS6Z+yRTpPHc6srtByg==", "dependencies": { - "@vue/runtime-core": "3.2.22", - "@vue/shared": "3.2.22", + "@vue/runtime-core": "3.2.23", + "@vue/shared": "3.2.23", "csstype": "^2.6.8" } }, "node_modules/@vue/server-renderer": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.22.tgz", - "integrity": "sha512-jCwbQgKPXiXoH9VS9F7K+gyEvEMrjutannwEZD1R8fQ9szmOTqC+RRbIY3Uf2ibQjZtZ8DV9a4FjxICvd9zZlQ==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.23.tgz", + "integrity": "sha512-mgQ2VAE5WjeZELJKNbwE69uiBNpN+3LyL0ZDki1bJWVwHD2fhPfx7pwyYuiucE81xz2LxVsyGxhKKUL997g8vw==", "dependencies": { - "@vue/compiler-ssr": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/compiler-ssr": "3.2.23", + "@vue/shared": "3.2.23" }, "peerDependencies": { - "vue": "3.2.22" + "vue": "3.2.23" } }, "node_modules/@vue/shared": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.22.tgz", - "integrity": "sha512-qWVav014mpjEtbWbEgl0q9pEyrrIySKum8UVYjwhC6njrKzknLZPvfuYdQyVbApsqr94tf/3dP4pCuZmmjdCWQ==" + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.23.tgz", + "integrity": "sha512-U+/Jefa0QfXUF2qVy9Dqlrb6HKJSr9/wJcM66wXmWcTOoqg7hOWzF4qruDle51pyF4x3wMn6TSH54UdjKjCKMA==" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", @@ -2718,6 +2765,45 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -3871,12 +3957,12 @@ } }, "node_modules/compression-webpack-plugin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-9.0.0.tgz", - "integrity": "sha512-V2KmQqaUkErPT+ZcUGHa8zWpIw1oTYaC7wjGewJm053GWAoY04GfU5B/NZ/JSz1eFp9MggMdLQpEHe1TJAQY1A==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-9.0.1.tgz", + "integrity": "sha512-vqlhZIPSyCpy6eaYWy8iPhteLWpARKotRiN5B/jr7lLowJv1GVc98Snn1Dcxe0+SKbfydLu7qZcnNuP+AyG19Q==", "dev": true, "dependencies": { - "schema-utils": "^3.1.0", + "schema-utils": "^4.0.0", "serialize-javascript": "^6.0.0" }, "engines": { @@ -3890,18 +3976,53 @@ "webpack": "^5.1.0" } }, + "node_modules/compression-webpack-plugin/node_modules/ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/compression-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/compression-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/compression-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -4303,15 +4424,16 @@ } }, "node_modules/css-minimizer-webpack-plugin": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.1.3.tgz", - "integrity": "sha512-x+6kzXprepysouo513zKibWCbWTGIvH9OrEsMRRV8EcJ7vYY/zRg0lR8tCzMHMap+lhNPOrYCdDagjRmfnGGxw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-5q4myvkmm29jRlI73Fl8Mc008i6o6hCEKnV6/fOrzRVDWD6EFGwDRX+SM2qCVeZ7XiztRDKHpTGDUeUMAOOagg==", "dev": true, "dependencies": { + "@types/cssnano": "^4.0.1", "cssnano": "^5.0.6", "jest-worker": "^27.0.2", "postcss": "^8.3.5", - "schema-utils": "^3.1.0", + "schema-utils": "^4.0.0", "serialize-javascript": "^6.0.0", "source-map": "^0.6.1" }, @@ -4337,18 +4459,53 @@ } } }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -4436,12 +4593,12 @@ } }, "node_modules/cssnano": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.10.tgz", - "integrity": "sha512-YfNhVJJ04imffOpbPbXP2zjIoByf0m8E2c/s/HnvSvjXgzXMfgopVjAEGvxYOjkOpWuRQDg/OZFjO7WW94Ri8w==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.12.tgz", + "integrity": "sha512-U38V4x2iJ3ijPdeWqUrEr4eKBB5PbEKsNP5T8xcik2Au3LeMtiMHX0i2Hu9k51FcKofNZumbrcdC6+a521IUHg==", "dev": true, "dependencies": { - "cssnano-preset-default": "^5.1.6", + "cssnano-preset-default": "^5.1.8", "is-resolvable": "^1.1.0", "lilconfig": "^2.0.3", "yaml": "^1.10.2" @@ -4458,9 +4615,9 @@ } }, "node_modules/cssnano-preset-default": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.7.tgz", - "integrity": "sha512-bWDjtTY+BOqrqBtsSQIbN0RLGD2Yr2CnecpP0ydHNafh9ZUEre8c8VYTaH9FEbyOt0eIfEUAYYk5zj92ioO8LA==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.8.tgz", + "integrity": "sha512-zWMlP0+AMPBVE852SqTrP0DnhTcTA2C1wAF92TKZ3Va+aUVqLIhkqKlnJIXXdqXD7RN+S1ujuWmNpvrJBiM/vg==", "dev": true, "dependencies": { "css-declaration-sorter": "^6.0.3", @@ -4488,7 +4645,7 @@ "postcss-normalize-url": "^5.0.3", "postcss-normalize-whitespace": "^5.0.1", "postcss-ordered-values": "^5.0.2", - "postcss-reduce-initial": "^5.0.1", + "postcss-reduce-initial": "^5.0.2", "postcss-reduce-transforms": "^5.0.1", "postcss-svgo": "^5.0.3", "postcss-unique-selectors": "^5.0.2" @@ -6599,9 +6756,9 @@ "dev": true }, "node_modules/http-parser-js": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", + "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==", "dev": true }, "node_modules/http-proxy": { @@ -6809,51 +6966,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/internal-ip": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", - "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", - "dev": true, - "dependencies": { - "default-gateway": "^6.0.0", - "ipaddr.js": "^1.9.1", - "is-ip": "^3.1.0", - "p-event": "^4.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/internal-ip?sponsor=1" - } - }, - "node_modules/internal-ip/node_modules/p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "dependencies": { - "p-timeout": "^3.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/internal-ip/node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/into-stream": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", @@ -6873,15 +6985,6 @@ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", "dev": true }, - "node_modules/ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -7067,18 +7170,6 @@ "node": ">=8" } }, - "node_modules/is-ip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", - "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", - "dev": true, - "dependencies": { - "ip-regex": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-natural-number": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", @@ -9252,13 +9343,13 @@ } }, "node_modules/postcss-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.0.tgz", - "integrity": "sha512-H9hv447QjQJVDbHj3OUdciyAXY3v5+UDduzEytAlZCVHCpNAAg/mCSwhYYqZr9BiGYhmYspU8QXxZwiHTLn3yA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", "dev": true, "dependencies": { "cosmiconfig": "^7.0.0", - "klona": "^2.0.4", + "klona": "^2.0.5", "semver": "^7.3.5" }, "engines": { @@ -9615,12 +9706,12 @@ } }, "node_modules/postcss-reduce-initial": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz", - "integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz", + "integrity": "sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==", "dev": true, "dependencies": { - "browserslist": "^4.16.0", + "browserslist": "^4.16.6", "caniuse-api": "^3.0.0" }, "engines": { @@ -9647,12 +9738,12 @@ } }, "node_modules/postcss-rtlcss": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-3.4.1.tgz", - "integrity": "sha512-4SOkC34IJ086dYjmqGCeIOqQe4JTDk+jwETvq1M/57+bQA6CXEWAjGtqifjcSH75nd0vfW7+hve0Ec4ZYHmMtA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-3.5.0.tgz", + "integrity": "sha512-S/k5PMHejw83R4Dj+8Fh+enEfLo/T8sl5KqlEyWffu6Ly9uWqURBi/pvcOnPk1AeUd60PIYhNijwUB7VEPC2Wg==", "dev": true, "dependencies": { - "rtlcss": "^3.3.0" + "rtlcss": "^3.5.0" }, "engines": { "node": ">=12.0.0" @@ -9829,9 +9920,9 @@ } }, "node_modules/quasar": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.3.2.tgz", - "integrity": "sha512-YqmKj3DKN1MWmjZVYXsjvoTjKS5GVwucK+tzIm3fNIybeV4GVp5YY8RXY5uQehMhZecmY24iKfJaS6tQwFHSQw==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.3.3.tgz", + "integrity": "sha512-0Q/OWX61IHIIljNUBTibR4bB0uXzR+ZtSa8y8jxerNiRoiIbqdo+FMHCRBvPr/3RUDqQ680YgHVjQEDpUCvM1Q==", "engines": { "node": ">= 10.18.1", "npm": ">= 6.13.4", @@ -11882,15 +11973,15 @@ } }, "node_modules/vue": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.22.tgz", - "integrity": "sha512-KD5nZpXVZquOC6926Xnp3zOvswrUyO9Rya7ZUoxWFQEjFDW4iACtwzubRB4Um2Om9kj6CaJOqAVRDSFlqLpdgw==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.23.tgz", + "integrity": "sha512-MGp9JZC37lzGhwSu6c1tQxrQbXbw7XKFqtYh7SFwNrNK899FPxGAHwSHMZijMChTSC3uZrD2BGO/3EHOgMJ0cw==", "dependencies": { - "@vue/compiler-dom": "3.2.22", - "@vue/compiler-sfc": "3.2.22", - "@vue/runtime-dom": "3.2.22", - "@vue/server-renderer": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/compiler-dom": "3.2.23", + "@vue/compiler-sfc": "3.2.23", + "@vue/runtime-dom": "3.2.23", + "@vue/server-renderer": "3.2.23", + "@vue/shared": "3.2.23" } }, "node_modules/vue-loader": { @@ -12121,16 +12212,16 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.2.1.tgz", - "integrity": "sha512-Kx1X+36Rn9JaZcQMrJ7qN3PMAuKmEDD9ZISjUj3Cgq4A6PtwYsC4mpaKotSRYH3iOF6HsUa8viHKS59FlyVifQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.2.2.tgz", + "integrity": "sha512-DjZyYrsHhkikAFNvSNKrpnziXukU1EChFAh9j4LAm6ndPLPW8cN0KhM7T+RAiOqsQ6ABfQ8hoKIs9IWMTjov+w==", "dev": true, "dependencies": { "colorette": "^2.0.10", "memfs": "^3.2.2", "mime-types": "^2.1.31", "range-parser": "^1.2.1", - "schema-utils": "^3.1.0" + "schema-utils": "^4.0.0" }, "engines": { "node": ">= 12.13.0" @@ -12143,18 +12234,53 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -12162,9 +12288,9 @@ } }, "node_modules/webpack-dev-server": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.4.0.tgz", - "integrity": "sha512-+S0XRIbsopVjPFjCO8I07FXYBWYqkFmuP56ucGMTs2hA/gV4q2M9xTmNo5Tg4o8ffRR+Nm3AsXnQXxKRyYovrA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.6.0.tgz", + "integrity": "sha512-oojcBIKvx3Ya7qs1/AVWHDgmP1Xml8rGsEBnSobxU/UJSX1xP1GPM3MwsAnDzvqcVmVki8tV7lbcsjEjk0PtYg==", "dev": true, "dependencies": { "ansi-html-community": "^0.0.8", @@ -12173,17 +12299,17 @@ "colorette": "^2.0.10", "compression": "^1.7.4", "connect-history-api-fallback": "^1.6.0", + "default-gateway": "^6.0.3", "del": "^6.0.0", "express": "^4.17.1", "graceful-fs": "^4.2.6", "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.0", - "internal-ip": "^6.2.0", "ipaddr.js": "^2.0.1", "open": "^8.0.9", "p-retry": "^4.5.0", "portfinder": "^1.0.28", - "schema-utils": "^3.1.0", + "schema-utils": "^4.0.0", "selfsigned": "^1.10.11", "serve-index": "^1.9.1", "sockjs": "^0.3.21", @@ -12208,6 +12334,34 @@ } } }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, "node_modules/webpack-dev-server/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -12229,6 +12383,12 @@ "node": ">= 10" } }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/webpack-dev-server/node_modules/open": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", @@ -12247,17 +12407,18 @@ } }, "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -12280,9 +12441,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz", + "integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -13859,9 +14020,9 @@ "dev": true }, "@quasar/app": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@quasar/app/-/app-3.2.3.tgz", - "integrity": "sha512-bHANWxtN2IOYhfKRGNadfGuP5NHuAIcvCgS8MVxGU/LMEwBZX8Q7YwYYid2z7gO9G0pCd2d3RH9aQ1IFMeWGRA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@quasar/app/-/app-3.2.4.tgz", + "integrity": "sha512-iiQDnKs/t+qCFxNHSi2knhsIzS34jVLwfI4FbFwZLDyOEmocEXp7h4Y8nAxTLPxQBM2zUc/Xv1QBvmw0t0iS7A==", "dev": true, "requires": { "@quasar/babel-preset-app": "2.0.1", @@ -13871,19 +14032,19 @@ "@types/cordova": "0.0.34", "@types/express": "4.17.13", "@types/webpack-bundle-analyzer": "4.4.1", - "@types/webpack-dev-server": "4.3.1", + "@types/webpack-dev-server": "4.5.0", "archiver": "5.3.0", "autoprefixer": "10.4.0", "browserslist": "^4.12.0", "chalk": "4.1.2", "chokidar": "3.5.2", - "ci-info": "3.2.0", - "compression-webpack-plugin": "9.0.0", + "ci-info": "3.3.0", + "compression-webpack-plugin": "9.0.1", "copy-webpack-plugin": "9.1.0", "cross-spawn": "7.0.3", "css-loader": "5.2.6", - "css-minimizer-webpack-plugin": "3.1.3", - "cssnano": "5.0.10", + "css-minimizer-webpack-plugin": "3.2.0", + "cssnano": "5.0.12", "dot-prop": "6.0.1", "elementtree": "0.1.7", "error-stack-parser": "2.0.6", @@ -13910,8 +14071,8 @@ "open": "7.1.0", "ouch": "2.0.0", "postcss": "^8.2.10", - "postcss-loader": "6.2.0", - "postcss-rtlcss": "3.4.1", + "postcss-loader": "6.2.1", + "postcss-rtlcss": "3.5.0", "pretty-error": "4.0.0", "register-service-worker": "1.7.2", "sass": "1.32.12", @@ -13922,16 +14083,24 @@ "ts-loader": "9.2.5", "typescript": "4.4.2", "url-loader": "4.1.1", - "vue": "3.2.22", + "vue": "3.2.23", "vue-loader": "16.8.3", "vue-router": "4.0.12", "vue-style-loader": "4.1.3", "webpack": "^5.58.1", "webpack-bundle-analyzer": "4.5.0", "webpack-chain": "6.5.1", - "webpack-dev-server": "4.4.0", + "webpack-dev-server": "4.6.0", "webpack-merge": "5.8.0", "webpack-node-externals": "3.0.0" + }, + "dependencies": { + "ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + } } }, "@quasar/babel-preset-app": { @@ -14028,9 +14197,9 @@ } }, "@quasar/extras": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.12.0.tgz", - "integrity": "sha512-X4oBMf5xcwk8+z2SrVU3AJ2dbFWZ4+LkjZCcXf4sgfY652CatzX+uaZl5UJtQEnl62PwwFTSPXPGy8t0uWF3sA==" + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@quasar/extras/-/extras-1.12.1.tgz", + "integrity": "sha512-EwOnaJEDHo9zCnJzd1sFw1sfMAAq8cJaIjzr2+A9o2NcVLaIhD7YAaJdlIdcNmQnyuPAiq9NghUize8lCS0epw==" }, "@quasar/fastclick": { "version": "1.1.4", @@ -14069,9 +14238,9 @@ "dev": true }, "@types/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", "dev": true, "requires": { "@types/connect": "*", @@ -14122,6 +14291,39 @@ "integrity": "sha1-6nrd907Ow9dimCegw54smt3HPQQ=", "dev": true }, + "@types/cssnano": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/cssnano/-/cssnano-4.0.1.tgz", + "integrity": "sha512-hGOroxRTBkYl5gSBRJOffhV4+io+Y2bFX1VP7LgKEVHJt/LPPJaWUIuDAz74Vlp7l7hCDZfaDi7iPxwNwuVA4Q==", + "dev": true, + "requires": { + "postcss": "5 - 7" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "@types/eslint": { "version": "7.28.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz", @@ -14161,9 +14363,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", - "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", + "version": "4.17.26", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.26.tgz", + "integrity": "sha512-zeu3tpouA043RHxW0gzRxwCHchMgftE8GArRsvYT0ByDMbn19olQHx5jLue0LxWY6iYtXb7rXmuVtSkhy9YZvQ==", "dev": true, "requires": { "@types/node": "*", @@ -14276,9 +14478,9 @@ } }, "@types/webpack-dev-server": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-4.3.1.tgz", - "integrity": "sha512-sFAFnvz1Ah17Kt4pFjATbPtuAmFS9s2dUUKhpz0kkB+X7vpJF2tbO7JoHP42od0SKijtrB7CHbsa3/lnztjpvw==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-4.5.0.tgz", + "integrity": "sha512-HMb6pZPANObue3LwbdpQLWzQyF9O0wntiPyXj4vGutlAbNKTXH4hDCHaZyfvfZDmFn+5HprrWHm1TGt3awNr/A==", "dev": true, "requires": { "@types/bonjour": "*", @@ -14293,12 +14495,12 @@ } }, "@vue/compiler-core": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.22.tgz", - "integrity": "sha512-uAkovrVeTcjzpiM4ECmVaMrv/bjdgAaLzvjcGqQPBEyUrcqsCgccT9fHJ/+hWVGhyMahmBwLqcn4guULNx7sdw==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.23.tgz", + "integrity": "sha512-4ZhiI/orx+7EJ1B+0zjgvXMV2uRN+XBfG06UN2sJfND9rH5gtEQT3QmO4erum1o6Irl7y754W8/KSaDJh4EUQg==", "requires": { "@babel/parser": "^7.15.0", - "@vue/shared": "3.2.22", + "@vue/shared": "3.2.23", "estree-walker": "^2.0.2", "source-map": "^0.6.1" }, @@ -14311,25 +14513,25 @@ } }, "@vue/compiler-dom": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.22.tgz", - "integrity": "sha512-VZdsw/VuO1ODs8K7NQwnMQzKITDkIFlYYC03SVnunuf6eNRxBPEonSyqbWNoo6qNaHAEBTG6VVcZC5xC9bAx1g==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.23.tgz", + "integrity": "sha512-X2Nw8QFc5lgoK3kio5ktM95nqmLUH+q+N/PbV4kCHzF1avqv/EGLnAhaaF0Iu4bewNvHJAAhhwPZFeoV/22nbw==", "requires": { - "@vue/compiler-core": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/compiler-core": "3.2.23", + "@vue/shared": "3.2.23" } }, "@vue/compiler-sfc": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.22.tgz", - "integrity": "sha512-tWRQ5ge1tsTDhUwHgueicKJ8rYm6WUVAPTaIpFW3GSwZKcOEJ2rXdfkHFShNVGupeRALz2ET2H84OL0GeRxY0A==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.23.tgz", + "integrity": "sha512-Aw+pb50Q5zTjyvWod8mNKmYZDRGHJBptmNNWE+84ZxrzEztPgMz8cNYIzWGbwcFVkmJlhvioAMvKnB+LM/sjSA==", "requires": { "@babel/parser": "^7.15.0", - "@vue/compiler-core": "3.2.22", - "@vue/compiler-dom": "3.2.22", - "@vue/compiler-ssr": "3.2.22", - "@vue/ref-transform": "3.2.22", - "@vue/shared": "3.2.22", + "@vue/compiler-core": "3.2.23", + "@vue/compiler-dom": "3.2.23", + "@vue/compiler-ssr": "3.2.23", + "@vue/ref-transform": "3.2.23", + "@vue/shared": "3.2.23", "estree-walker": "^2.0.2", "magic-string": "^0.25.7", "postcss": "^8.1.10", @@ -14344,12 +14546,12 @@ } }, "@vue/compiler-ssr": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.22.tgz", - "integrity": "sha512-Cl6aoLJtXzzBkk1sKod8S0WBJLts3+ugVC91d22gGpbkw/64WnF12tOZi7Rg54PPLi1NovqyNWPsLH/SAFcu+w==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.23.tgz", + "integrity": "sha512-Bqzn4jFyXPK1Ehqiq7e/czS8n62gtYF1Zfeu0DrR5uv+SBllh7LIvZjZU6+c8qbocAd3/T3I3gn2cZGmnDb6zg==", "requires": { - "@vue/compiler-dom": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/compiler-dom": "3.2.23", + "@vue/shared": "3.2.23" } }, "@vue/devtools-api": { @@ -14358,57 +14560,57 @@ "integrity": "sha512-21u2jFOk8jbAneeGpDwZQ0W66RJa0IBDUyVl6SgKnn2cRFjLWzKj+ukXjpLhYr1KASyCe5E5U4jXwChVo0YUAw==" }, "@vue/reactivity": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.22.tgz", - "integrity": "sha512-xNkLAItjI0xB+lFeDgKCrSItmrHTaAzSnt8LmdSCPQnDyarmzbi/u4ESQnckWvlL7lSRKiEaOvblaNyqAa7OnQ==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.23.tgz", + "integrity": "sha512-8RGVr/5Kpgb/EkCjgHXqttgA5IMc6n0lIXFY4TVbMkzdXrvaIhzBd7Te44oIDsTSYVKZLpfHd6/wEnuDqE8vFw==", "requires": { - "@vue/shared": "3.2.22" + "@vue/shared": "3.2.23" } }, "@vue/ref-transform": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.22.tgz", - "integrity": "sha512-qalVWbq5xWWxLZ0L9OroBg/JZhzavQuCcDXblfErxyDEH6Xc5gIJ4feo1SVCICFzhAUgLgQTdSFLpgjBawbFpw==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/ref-transform/-/ref-transform-3.2.23.tgz", + "integrity": "sha512-gW0GD2PSAs/th7mC7tPB/UwpIQxclbApVtsDtscDmOJXb2+cdu60ny+SuHNgfrlUT/JqWKQHq7jFKO4woxLNaA==", "requires": { "@babel/parser": "^7.15.0", - "@vue/compiler-core": "3.2.22", - "@vue/shared": "3.2.22", + "@vue/compiler-core": "3.2.23", + "@vue/shared": "3.2.23", "estree-walker": "^2.0.2", "magic-string": "^0.25.7" } }, "@vue/runtime-core": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.22.tgz", - "integrity": "sha512-e7WOC55wmHPvmoVUk9VBe/Z9k5bJfWJfVIlkUkiADJn0bOgQD29oh/GS14Kb3aEJXIHLI17Em6+HxNut1sIh7Q==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.23.tgz", + "integrity": "sha512-wSI5lmY2kCGLf89iiygqxVh6/5bsawz78Me9n1x4U2bHnN0yf3PWyuhN0WgIE8VfEaF7e75E333uboNEIFjgkg==", "requires": { - "@vue/reactivity": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/reactivity": "3.2.23", + "@vue/shared": "3.2.23" } }, "@vue/runtime-dom": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.22.tgz", - "integrity": "sha512-w7VHYJoliLRTLc5beN77wxuOjla4v9wr2FF22xpZFYBmH4U1V7HkYhoHc1BTuNghI15CXT1tNIMhibI1nrQgdw==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.23.tgz", + "integrity": "sha512-z6lp0888NkLmxD9j2sGoll8Kb7J743s8s6w7GbiyUc4WZwm0KJ35B4qTFDMoIU0G7CatS6Z+yRTpPHc6srtByg==", "requires": { - "@vue/runtime-core": "3.2.22", - "@vue/shared": "3.2.22", + "@vue/runtime-core": "3.2.23", + "@vue/shared": "3.2.23", "csstype": "^2.6.8" } }, "@vue/server-renderer": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.22.tgz", - "integrity": "sha512-jCwbQgKPXiXoH9VS9F7K+gyEvEMrjutannwEZD1R8fQ9szmOTqC+RRbIY3Uf2ibQjZtZ8DV9a4FjxICvd9zZlQ==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.23.tgz", + "integrity": "sha512-mgQ2VAE5WjeZELJKNbwE69uiBNpN+3LyL0ZDki1bJWVwHD2fhPfx7pwyYuiucE81xz2LxVsyGxhKKUL997g8vw==", "requires": { - "@vue/compiler-ssr": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/compiler-ssr": "3.2.23", + "@vue/shared": "3.2.23" } }, "@vue/shared": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.22.tgz", - "integrity": "sha512-qWVav014mpjEtbWbEgl0q9pEyrrIySKum8UVYjwhC6njrKzknLZPvfuYdQyVbApsqr94tf/3dP4pCuZmmjdCWQ==" + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.23.tgz", + "integrity": "sha512-U+/Jefa0QfXUF2qVy9Dqlrb6HKJSr9/wJcM66wXmWcTOoqg7hOWzF4qruDle51pyF4x3wMn6TSH54UdjKjCKMA==" }, "@webassemblyjs/ast": { "version": "1.11.1", @@ -14630,6 +14832,35 @@ "uri-js": "^4.2.2" } }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, "ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -15555,24 +15786,52 @@ } }, "compression-webpack-plugin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-9.0.0.tgz", - "integrity": "sha512-V2KmQqaUkErPT+ZcUGHa8zWpIw1oTYaC7wjGewJm053GWAoY04GfU5B/NZ/JSz1eFp9MggMdLQpEHe1TJAQY1A==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-9.0.1.tgz", + "integrity": "sha512-vqlhZIPSyCpy6eaYWy8iPhteLWpARKotRiN5B/jr7lLowJv1GVc98Snn1Dcxe0+SKbfydLu7qZcnNuP+AyG19Q==", "dev": true, "requires": { - "schema-utils": "^3.1.0", + "schema-utils": "^4.0.0", "serialize-javascript": "^6.0.0" }, "dependencies": { + "ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" } }, "serialize-javascript": { @@ -15865,28 +16124,57 @@ } }, "css-minimizer-webpack-plugin": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.1.3.tgz", - "integrity": "sha512-x+6kzXprepysouo513zKibWCbWTGIvH9OrEsMRRV8EcJ7vYY/zRg0lR8tCzMHMap+lhNPOrYCdDagjRmfnGGxw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-5q4myvkmm29jRlI73Fl8Mc008i6o6hCEKnV6/fOrzRVDWD6EFGwDRX+SM2qCVeZ7XiztRDKHpTGDUeUMAOOagg==", "dev": true, "requires": { + "@types/cssnano": "^4.0.1", "cssnano": "^5.0.6", "jest-worker": "^27.0.2", "postcss": "^8.3.5", - "schema-utils": "^3.1.0", + "schema-utils": "^4.0.0", "serialize-javascript": "^6.0.0", "source-map": "^0.6.1" }, "dependencies": { + "ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" } }, "serialize-javascript": { @@ -15950,21 +16238,21 @@ "dev": true }, "cssnano": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.10.tgz", - "integrity": "sha512-YfNhVJJ04imffOpbPbXP2zjIoByf0m8E2c/s/HnvSvjXgzXMfgopVjAEGvxYOjkOpWuRQDg/OZFjO7WW94Ri8w==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.0.12.tgz", + "integrity": "sha512-U38V4x2iJ3ijPdeWqUrEr4eKBB5PbEKsNP5T8xcik2Au3LeMtiMHX0i2Hu9k51FcKofNZumbrcdC6+a521IUHg==", "dev": true, "requires": { - "cssnano-preset-default": "^5.1.6", + "cssnano-preset-default": "^5.1.8", "is-resolvable": "^1.1.0", "lilconfig": "^2.0.3", "yaml": "^1.10.2" } }, "cssnano-preset-default": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.7.tgz", - "integrity": "sha512-bWDjtTY+BOqrqBtsSQIbN0RLGD2Yr2CnecpP0ydHNafh9ZUEre8c8VYTaH9FEbyOt0eIfEUAYYk5zj92ioO8LA==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.1.8.tgz", + "integrity": "sha512-zWMlP0+AMPBVE852SqTrP0DnhTcTA2C1wAF92TKZ3Va+aUVqLIhkqKlnJIXXdqXD7RN+S1ujuWmNpvrJBiM/vg==", "dev": true, "requires": { "css-declaration-sorter": "^6.0.3", @@ -15992,7 +16280,7 @@ "postcss-normalize-url": "^5.0.3", "postcss-normalize-whitespace": "^5.0.1", "postcss-ordered-values": "^5.0.2", - "postcss-reduce-initial": "^5.0.1", + "postcss-reduce-initial": "^5.0.2", "postcss-reduce-transforms": "^5.0.1", "postcss-svgo": "^5.0.3", "postcss-unique-selectors": "^5.0.2" @@ -17643,9 +17931,9 @@ } }, "http-parser-js": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.5.tgz", + "integrity": "sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA==", "dev": true }, "http-proxy": { @@ -17797,38 +18085,6 @@ } } }, - "internal-ip": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-6.2.0.tgz", - "integrity": "sha512-D8WGsR6yDt8uq7vDMu7mjcR+yRMm3dW8yufyChmszWRjcSHuxLBkR3GdS2HZAjodsaGuCvXeEJpueisXJULghg==", - "dev": true, - "requires": { - "default-gateway": "^6.0.0", - "ipaddr.js": "^1.9.1", - "is-ip": "^3.1.0", - "p-event": "^4.2.0" - }, - "dependencies": { - "p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "requires": { - "p-timeout": "^3.1.0" - } - }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - } - } - }, "into-stream": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", @@ -17845,12 +18101,6 @@ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", "dev": true }, - "ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", - "dev": true - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -17978,15 +18228,6 @@ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true }, - "is-ip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-3.1.0.tgz", - "integrity": "sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==", - "dev": true, - "requires": { - "ip-regex": "^4.0.0" - } - }, "is-natural-number": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", @@ -19653,13 +19894,13 @@ "requires": {} }, "postcss-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.0.tgz", - "integrity": "sha512-H9hv447QjQJVDbHj3OUdciyAXY3v5+UDduzEytAlZCVHCpNAAg/mCSwhYYqZr9BiGYhmYspU8QXxZwiHTLn3yA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", + "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", "dev": true, "requires": { "cosmiconfig": "^7.0.0", - "klona": "^2.0.4", + "klona": "^2.0.5", "semver": "^7.3.5" }, "dependencies": { @@ -19882,12 +20123,12 @@ } }, "postcss-reduce-initial": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz", - "integrity": "sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz", + "integrity": "sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==", "dev": true, "requires": { - "browserslist": "^4.16.0", + "browserslist": "^4.16.6", "caniuse-api": "^3.0.0" } }, @@ -19902,12 +20143,12 @@ } }, "postcss-rtlcss": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-3.4.1.tgz", - "integrity": "sha512-4SOkC34IJ086dYjmqGCeIOqQe4JTDk+jwETvq1M/57+bQA6CXEWAjGtqifjcSH75nd0vfW7+hve0Ec4ZYHmMtA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/postcss-rtlcss/-/postcss-rtlcss-3.5.0.tgz", + "integrity": "sha512-S/k5PMHejw83R4Dj+8Fh+enEfLo/T8sl5KqlEyWffu6Ly9uWqURBi/pvcOnPk1AeUd60PIYhNijwUB7VEPC2Wg==", "dev": true, "requires": { - "rtlcss": "^3.3.0" + "rtlcss": "^3.5.0" } }, "postcss-selector-parser": { @@ -20040,9 +20281,9 @@ "dev": true }, "quasar": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.3.2.tgz", - "integrity": "sha512-YqmKj3DKN1MWmjZVYXsjvoTjKS5GVwucK+tzIm3fNIybeV4GVp5YY8RXY5uQehMhZecmY24iKfJaS6tQwFHSQw==" + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/quasar/-/quasar-2.3.3.tgz", + "integrity": "sha512-0Q/OWX61IHIIljNUBTibR4bB0uXzR+ZtSa8y8jxerNiRoiIbqdo+FMHCRBvPr/3RUDqQ680YgHVjQEDpUCvM1Q==" }, "query-string": { "version": "5.1.1", @@ -21610,15 +21851,15 @@ "dev": true }, "vue": { - "version": "3.2.22", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.22.tgz", - "integrity": "sha512-KD5nZpXVZquOC6926Xnp3zOvswrUyO9Rya7ZUoxWFQEjFDW4iACtwzubRB4Um2Om9kj6CaJOqAVRDSFlqLpdgw==", + "version": "3.2.23", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.2.23.tgz", + "integrity": "sha512-MGp9JZC37lzGhwSu6c1tQxrQbXbw7XKFqtYh7SFwNrNK899FPxGAHwSHMZijMChTSC3uZrD2BGO/3EHOgMJ0cw==", "requires": { - "@vue/compiler-dom": "3.2.22", - "@vue/compiler-sfc": "3.2.22", - "@vue/runtime-dom": "3.2.22", - "@vue/server-renderer": "3.2.22", - "@vue/shared": "3.2.22" + "@vue/compiler-dom": "3.2.23", + "@vue/compiler-sfc": "3.2.23", + "@vue/runtime-dom": "3.2.23", + "@vue/server-renderer": "3.2.23", + "@vue/shared": "3.2.23" } }, "vue-loader": { @@ -21828,35 +22069,63 @@ } }, "webpack-dev-middleware": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.2.1.tgz", - "integrity": "sha512-Kx1X+36Rn9JaZcQMrJ7qN3PMAuKmEDD9ZISjUj3Cgq4A6PtwYsC4mpaKotSRYH3iOF6HsUa8viHKS59FlyVifQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.2.2.tgz", + "integrity": "sha512-DjZyYrsHhkikAFNvSNKrpnziXukU1EChFAh9j4LAm6ndPLPW8cN0KhM7T+RAiOqsQ6ABfQ8hoKIs9IWMTjov+w==", "dev": true, "requires": { "colorette": "^2.0.10", "memfs": "^3.2.2", "mime-types": "^2.1.31", "range-parser": "^1.2.1", - "schema-utils": "^3.1.0" + "schema-utils": "^4.0.0" }, "dependencies": { + "ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" } } } }, "webpack-dev-server": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.4.0.tgz", - "integrity": "sha512-+S0XRIbsopVjPFjCO8I07FXYBWYqkFmuP56ucGMTs2hA/gV4q2M9xTmNo5Tg4o8ffRR+Nm3AsXnQXxKRyYovrA==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.6.0.tgz", + "integrity": "sha512-oojcBIKvx3Ya7qs1/AVWHDgmP1Xml8rGsEBnSobxU/UJSX1xP1GPM3MwsAnDzvqcVmVki8tV7lbcsjEjk0PtYg==", "dev": true, "requires": { "ansi-html-community": "^0.0.8", @@ -21865,17 +22134,17 @@ "colorette": "^2.0.10", "compression": "^1.7.4", "connect-history-api-fallback": "^1.6.0", + "default-gateway": "^6.0.3", "del": "^6.0.0", "express": "^4.17.1", "graceful-fs": "^4.2.6", "html-entities": "^2.3.2", "http-proxy-middleware": "^2.0.0", - "internal-ip": "^6.2.0", "ipaddr.js": "^2.0.1", "open": "^8.0.9", "p-retry": "^4.5.0", "portfinder": "^1.0.28", - "schema-utils": "^3.1.0", + "schema-utils": "^4.0.0", "selfsigned": "^1.10.11", "serve-index": "^1.9.1", "sockjs": "^0.3.21", @@ -21886,6 +22155,27 @@ "ws": "^8.1.0" }, "dependencies": { + "ajv": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz", + "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, "ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -21898,6 +22188,12 @@ "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", "dev": true }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "open": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", @@ -21910,14 +22206,15 @@ } }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", "dev": true, "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" } }, "strip-ansi": { @@ -21930,9 +22227,9 @@ } }, "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz", + "integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==", "dev": true, "requires": {} } diff --git a/web/package.json b/web/package.json index 4c10570af6..bf229d2a94 100644 --- a/web/package.json +++ b/web/package.json @@ -10,18 +10,18 @@ "test:e2e:ci": "cross-env E2E_TEST=true start-test \"quasar dev\" http-get://localhost:8080 \"cypress run\"" }, "dependencies": { - "@quasar/extras": "^1.12.0", + "@quasar/extras": "^1.12.1", "apexcharts": "^3.27.1", "axios": "^0.24.0", "dotenv": "^8.6.0", "qrcode.vue": "^3.2.2", - "quasar": "^2.3.2", + "quasar": "^2.3.3", "vue3-ace-editor": "^2.2.1", "vue3-apexcharts": "^1.4.0", "vuex": "^4.0.2" }, "devDependencies": { - "@quasar/app": "^3.2.3", + "@quasar/app": "^3.2.4", "@quasar/cli": "^1.2.2" }, "browserslist": [ From 4760a287f6a67c777598268aba22eb763becfb34 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Wed, 1 Dec 2021 19:53:37 +0000 Subject: [PATCH 46/48] update docs --- docs/docs/contributing_using_a_remote_server.md | 3 ++- docs/docs/howitallworks.md | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/docs/contributing_using_a_remote_server.md b/docs/docs/contributing_using_a_remote_server.md index 8bf473c2e3..461e947b09 100644 --- a/docs/docs/contributing_using_a_remote_server.md +++ b/docs/docs/contributing_using_a_remote_server.md @@ -87,7 +87,8 @@ npm install -g @quasar/cli quasar dev ``` -!!!info If you receive a CORS error when trying to log into your server via localhost or IP, try the following +!!!info + If you receive a CORS error when trying to log into your server via localhost or IP, try the following ```bash rm -rf node_modules .quasar npm install diff --git a/docs/docs/howitallworks.md b/docs/docs/howitallworks.md index 129804eb6e..44be4d431d 100644 --- a/docs/docs/howitallworks.md +++ b/docs/docs/howitallworks.md @@ -216,8 +216,8 @@ The NATS API service appears to bridge the connection between the NATS server an === ":material-ubuntu: standard" - Service: `nats-api.service` - - Exec: `/usr/local/bin/nats-server --config /rmm/api/tacticalrmm/nats-rmm.conf` - - Config: `/rmm/api/tacticalrmm/nats-rmm.conf` + - Exec: `/usr/local/bin/nats-api --config /rmm/api/tacticalrmm/nats-api.conf` + - Config: `/rmm/api/tacticalrmm/nats-api.conf` - TLS: `/etc/letsencrypt/live/example.com/fullchain.pem` - Log: None @@ -370,15 +370,15 @@ If you have strict firewall rules these are the only outbound rules from the age 1. All agents have to be able to connect outbound to TRMM server on the 3 domain names on ports: 443 (agent and mesh) and 4222 (nats for checks/tasks/data) -2. The agent uses this to obtain public IP info: `curl https://icanhazip.tacticalrmm.io/` +2. The agent uses `https://icanhazip.tacticalrmm.io/` to get public IP info. If this site is down for whatever reason, the agent will fallback to `https://icanhazip.com` and then `https://ifconfig.co/ip` #### Unsigned Agents -Unsigned agents require access to: https://github.com/wh1te909/rmmagent/releases/* +Unsigned agents require access to: `https://github.com/wh1te909/rmmagent/releases/*` #### Signed Agents -Signed agents will require: https://exe.tacticalrmm.io/ and https://exe2.tacticalrmm.io/ for downloading/updating agents +Signed agents will require: `https://exe.tacticalrmm.io/` and `https://exe2.tacticalrmm.io/` for downloading/updating agents ### Services From 175486b7c4cbce50196fd00823af177d77d54550 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Thu, 2 Dec 2021 01:39:41 +0000 Subject: [PATCH 47/48] fix bug where reboot_required field was not being updated when agent didn't have a patch policy and setting was set to 'inherit' --- api/tacticalrmm/apiv3/views.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/api/tacticalrmm/apiv3/views.py b/api/tacticalrmm/apiv3/views.py index 6a4926bf17..a9397a5fbb 100644 --- a/api/tacticalrmm/apiv3/views.py +++ b/api/tacticalrmm/apiv3/views.py @@ -121,18 +121,18 @@ class WinUpdates(APIView): def put(self, request): agent = get_object_or_404(Agent, agent_id=request.data["agent_id"]) + + needs_reboot: bool = request.data["needs_reboot"] + agent.needs_reboot = needs_reboot + agent.save(update_fields=["needs_reboot"]) + reboot_policy: str = agent.get_patch_policy().reboot_after_install reboot = False if reboot_policy == "always": reboot = True - - if request.data["needs_reboot"]: - if reboot_policy == "required": - reboot = True - elif reboot_policy == "never": - agent.needs_reboot = True - agent.save(update_fields=["needs_reboot"]) + elif needs_reboot and reboot_policy == "required": + reboot = True if reboot: asyncio.run(agent.nats_cmd({"func": "rebootnow"}, wait=False)) From 9c0993dac8b750964280b464260bd0a798c2f89d Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Thu, 2 Dec 2021 07:50:52 +0000 Subject: [PATCH 48/48] bump version --- api/tacticalrmm/tacticalrmm/settings.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/tacticalrmm/tacticalrmm/settings.py b/api/tacticalrmm/tacticalrmm/settings.py index e9ccf3e5d2..aee8586844 100644 --- a/api/tacticalrmm/tacticalrmm/settings.py +++ b/api/tacticalrmm/tacticalrmm/settings.py @@ -15,22 +15,22 @@ AUTH_USER_MODEL = "accounts.User" # latest release -TRMM_VERSION = "0.10.2" +TRMM_VERSION = "0.10.3" # bump this version everytime vue code is changed # to alert user they need to manually refresh their browser -APP_VER = "0.0.152" +APP_VER = "0.0.153" # https://github.com/wh1te909/rmmagent -LATEST_AGENT_VER = "1.7.0" +LATEST_AGENT_VER = "1.7.1" -MESH_VER = "0.9.51" +MESH_VER = "0.9.55" NATS_SERVER_VER = "2.3.3" # for the update script, bump when need to recreate venv or npm install PIP_VER = "24" -NPM_VER = "25" +NPM_VER = "26" SETUPTOOLS_VER = "59.4.0" WHEEL_VER = "0.37.0"