jackailocal / updates /JackAILocal-Update.ps1
jackboy70's picture
Deploy: accurate lite-builder note
f25362a
Raw
History Blame Contribute Delete
1.88 kB
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)][string]$ManifestUrl,
[switch]$Apply
)
$ErrorActionPreference = "Stop"
$Root = Resolve-Path (Join-Path $PSScriptRoot "..")
$tmp = Join-Path $Root ".jackailocal\updates"
New-Item -ItemType Directory -Force -Path $tmp | Out-Null
$manifestPath = Join-Path $tmp "update-manifest.json"
$sigPath = Join-Path $tmp "update-manifest.json.sig"
$pubKeyPath = Join-Path $Root "config\update-public-key.xml"
if (!(Test-Path $pubKeyPath)) {
throw "Public key for update verification not found at: $pubKeyPath"
}
# Download manifest and signature
Invoke-WebRequest -Uri $ManifestUrl -OutFile $manifestPath
Invoke-WebRequest -Uri "$ManifestUrl.sig" -OutFile $sigPath
# Verify Signature
& (Join-Path $PSScriptRoot "Verify-SignedManifest.ps1") -ManifestPath $manifestPath -SignaturePath $sigPath -PublicKeyXmlPath $pubKeyPath
$manifest = Get-Content $manifestPath -Raw | ConvertFrom-Json
if ($manifest.product -ne "JackAILocal") { throw "Wrong product." }
$rootPath = [System.IO.Path]::GetFullPath($Root)
foreach ($file in $manifest.files) {
# Avoid Path Traversal Vulnerability
$dest = [System.IO.Path]::GetFullPath((Join-Path $rootPath $file.path))
if (-not $dest.StartsWith($rootPath, [System.StringComparison]::OrdinalIgnoreCase)) {
throw "Security error: Path traversal detected in file path: $($file.path)"
}
$download = Join-Path $tmp ([IO.Path]::GetFileName($file.path))
Invoke-WebRequest -Uri $file.url -OutFile $download
$h = (Get-FileHash -Algorithm SHA256 $download).Hash.ToLowerInvariant()
if ($h -ne $file.sha256.ToLowerInvariant()) { throw "Checksum failed: $($file.path)" }
if ($Apply) {
New-Item -ItemType Directory -Force -Path (Split-Path $dest) | Out-Null
Copy-Item $download $dest -Force
}
}
if (-not $Apply) { Write-Host "Dry-run update verified. Use -Apply to install." }