diff --git a/testTaskGate.ps1 b/testTaskGate.ps1 index 5f334b0..017465b 100644 --- a/testTaskGate.ps1 +++ b/testTaskGate.ps1 @@ -104,6 +104,97 @@ function Respond-HTML { $Context.Response.OutputStream.Close() } +# new helper to return JSON +function Respond-JSON { + param($Context, $Object) + $json = $Object | ConvertTo-Json -Depth 5 + $bytes = [Text.Encoding]::UTF8.GetBytes($json) + $Context.Response.ContentType = 'application/json' + $Context.Response.ContentLength64 = $bytes.Length + $Context.Response.OutputStream.Write($bytes,0,$bytes.Length) + $Context.Response.OutputStream.Close() +} + +#region Install-DattoRMM-Helper +function Install-DattoRMM-Helper { + param ( + [string]$ApiUrl, + [string]$ApiKey, + [string]$ApiSecretKey, + [switch]$FetchSitesOnly, + [string]$SiteName, + [string]$SiteUID + ) + if (-not $ApiUrl -or -not $ApiKey -or -not $ApiSecretKey) { + Write-LogHybrid -Message "Missing required parameters. Please provide ApiUrl, ApiKey, and ApiSecretKey." -Level "Error" -LogToEvent + return + } + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + Write-LogHybrid -Message "Fetching OAuth token..." -Level "Info" + try { + $securePassword = ConvertTo-SecureString -String 'public' -AsPlainText -Force + $apiGenToken = Invoke-WebRequest -Credential (New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ('public-client', $securePassword)) ` + -Uri ('{0}/auth/oauth/token' -f $ApiUrl) ` + -Method 'POST' ` + -ContentType 'application/x-www-form-urlencoded' ` + -Body ('grant_type=password&username={0}&password={1}' -f $ApiKey, $ApiSecretKey) ` + | ConvertFrom-Json + $requestToken = $apiGenToken.access_token + Write-LogHybrid -Message "OAuth token fetched successfully." -Level "Success" -LogToEvent + } catch { + Write-LogHybrid -Message "Failed to fetch OAuth token. Details: $($_.Exception.Message)" -Level "Error" -LogToEvent + return + } + $getHeaders = @{"Authorization" = "Bearer $requestToken"} + if ($FetchSitesOnly) { + Write-Host "Fetching list of sites from the Datto RMM API..." -ForegroundColor Cyan + try { + $getHeaders = @{"Authorization" = "Bearer $requestToken" } + $getSites = Invoke-WebRequest -Uri "$ApiUrl/api/v2/account/sites" -Method Get -Headers $getHeaders -ContentType "application/json" + $sitesJson = $getSites.Content | ConvertFrom-Json + $siteList = $sitesJson.sites | ForEach-Object { + [PSCustomObject]@{ + Name = $_.name + UID = $_.uid + } + } + Write-Host "Successfully fetched list of sites." -ForegroundColor Green + return $siteList + } + catch { + Write-Host "Failed to fetch sites from the API. Details: $($_.Exception.Message)" -ForegroundColor Red + return + } + } +} +#endregion + +# POST /getpw → read JSON body, call helper, return JSON +function Handle-FetchSites { + param($Context) + Write-Host "[Debug] Handle-FetchSites invoked" # ← add this + try { + $body = (New-Object IO.StreamReader $Context.Request.InputStream).ReadToEnd() + $pw = (ConvertFrom-Json $body).password + $sites = Install-DattoRMM-Helper ` + -ApiUrl $ApiUrl ` + -ApiKey $ApiKey ` + -ApiSecretKey $ApiSecretKey ` + -FetchSitesOnly + if (-not $sites) { $Context.Response.StatusCode = 500; $sites = @() } + $json = $sites | ConvertTo-Json -Depth 2 + $bytes = [Text.Encoding]::UTF8.GetBytes($json) + $Context.Response.ContentType = 'application/json' + $Context.Response.OutputStream.Write($bytes,0,$bytes.Length) + } catch { + $Context.Response.StatusCode = 500 + $Context.Response.ContentType = 'application/json' + $Context.Response.OutputStream.Write([Text.Encoding]::UTF8.GetBytes('[]'),0,2) + } finally { + $Context.Response.OutputStream.Close() + } +} + # On-boarding handlers function Set-SVSPowerPlan { @@ -190,6 +281,7 @@ $style = @' .logo-container { text-align:left; padding:20px; } .logo-container img { max-width:300px; height:auto; } + .subtitle { font-size: 1.2rem; color: var(--gray-color); margin-top: 0.5em; } .container { display:flex; height:100vh; overflow:hidden; } .sidebar { width:200px; background:var(--background-color); padding:10px; } @@ -291,6 +383,40 @@ $style = @' {{tasksJsAll}} ]; + // ======================================================================= + // Fetch Sites Handler + // ======================================================================= + async function fetchSites() { + const pwd = document.getElementById("Password").value; + if (!pwd) { alert("Please enter the password."); return; } + + try { + const resp = await fetch("/getpw", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ password: pwd }) + }); + if (!resp.ok) throw("HTTP " + resp.status); + + const sites = await resp.json(); + const dd = document.getElementById("dattoDropdown"); + dd.innerHTML = ""; // clear old + sites.forEach(s => { + const opt = document.createElement("option"); + opt.value = s.UID; + opt.text = s.Name; + dd.appendChild(opt); + }); + document.getElementById("dattoRmmContainer").style.display = "block"; + } + catch (e) { + console.error(e); + alert("Failed to fetch sites. Check password and try again."); + } + } + + + async function triggerInstall() { for (const t of tasks) { const cb = document.getElementById(t.id); @@ -342,11 +468,41 @@ $htmlTemplate = @"

On-Boarding

-
-{{onboardCheckboxes}} +

This new deployment method ensures everything is successfully deployed with greater ease!

+ + +
+ + + +
+ + + + + +
+ + +
+ +
+ +
+ + +
+ {{onboardCheckboxes}}
-
+

Off-Boarding

@@ -445,6 +601,12 @@ function Dispatch-Request { return } + # ---- Fetch Sites endpoint ---- + if ($Context.Request.HttpMethod -eq 'POST' -and $path -eq 'getpw') { + Handle-FetchSites $Context + return + } + # ---- Serve UI pages ---- if ($path -in @('', 'onboard', 'offboard', 'tweaks', 'SVSApps')) { $page = if ($path -eq '') { 'onboard' } else { $path } @@ -452,7 +614,7 @@ function Dispatch-Request { Respond-HTML $Context $html return } - + # ---- Task invocation ---- $task = $Global:Tasks | Where-Object Name -EQ $path if ($task) {