private/Get-UnraidCsrfToken.ps1
|
function Get-UnraidCsrfToken { [CmdletBinding()] param( [Parameter(Mandatory)] [string]$HtmlContent, [Parameter(Mandatory)] [string]$BaseUrl, [Parameter(Mandatory)] [Microsoft.PowerShell.Commands.WebRequestSession]$WebSession, [Parameter()] [bool]$SkipCertificateCheck ) process { # This isn't the prettiest. Using the API key seems to be the preferred method # Since the API doesn't provide the CSRF token directly, we have to hunt for the CSRF token in the HTML source # From testing, it seems to currently be in a JS variable like: var csrf_token = "XYZ"; function Find-TokenInHtml { param([string]$Content) # Look for var/let/const declarations # This is the method as of the current version (7.2.2) if ($Content -match "(?:var|let|const)\s+csrf_token\s*=\s*[`"']([^`"']+)[`"']") { return $matches[1] } # Look for it attached to the window object # This is more of a backup method in case Unraid changes their JS structure if ($Content -match "window\.csrf_token\s*=\s*[`"']([^`"']+)[`"']") { return $matches[1] } # Look for it inside a JSON object property # This is more of a backup method in case Unraid changes their JS structure # Probably won't work if the function hasn't already returned - but worth a shot? if ($Content -match "csrf_token\s*:\s*[`"']([^`"']+)[`"']") { return $matches[1] } return $null } # Check the page we just grabbed $token = Find-TokenInHtml -Content $HtmlContent if ($token) { Write-Verbose "CSRF token found." return $token } # If we missed it, it might be hiding on the dashboard (redirect happened?) Write-Verbose "Token wasn't on the login page. Checking the dashboard..." try { $dashParams = @{ Uri = $BaseUrl Method = 'Get' WebSession = $WebSession ErrorAction = "Stop" } if ($PSVersionTable.PSVersion.Major -ge 6 -and $SkipCertificateCheck) { $dashParams.Add('SkipCertificateCheck', $true) } $dashResponse = Invoke-WebRequest @dashParams $token = Find-TokenInHtml -Content $dashResponse.Content if ($token) { Write-Verbose "Found the token on the dashboard." return $token } } catch { throw [UnraidAuthException]::new("Unable to grab the dashboard page: $_") } # If we're here, Unraid changed their HTML and we ain't grabbing the token. Dump for debug. $dumpPath = Join-Path $env:TEMP "unraid_login_dump.html" $HtmlContent | Out-File $dumpPath throw [UnraidAuthException]::new("CSRF token is missing. The HTML was dumped to '$dumpPath' for debugging.") } } |