|
- $ErrorActionPreference = 'Stop'
- $projectRoot = Split-Path -Parent $PSScriptRoot
- $workPath = Join-Path $projectRoot ('temp\template-flow-' + [guid]::NewGuid().ToString('N'))
- $templateRoot = Join-Path $workPath 'templates'
- $assetRoot = Join-Path $templateRoot 'images'
- $databasePath = Join-Path $workPath 'test.mdb'
- $configPath = Join-Path $workPath 'test.ini'
- $previewRoot = Join-Path $workPath 'previews'
- $templatePath = Join-Path $templateRoot 'postcard.html'
- $imagePath = Join-Path $assetRoot 'logo.png'
- $scriptHost = Join-Path $env:SystemRoot 'SysWOW64\cscript.exe'
- $powerShellX86 = Join-Path $env:SystemRoot 'SysWOW64\WindowsPowerShell\v1.0\powershell.exe'
-
- try {
- $null = New-Item -ItemType Directory -Path $assetRoot -Force
- $example = Get-Content -LiteralPath (Join-Path $projectRoot 'config.example.ini') -Raw
- $example.Replace('DB_PATH=data/MassMailer.mdb', ('DB_PATH=' + $databasePath)).Replace(
- 'TEMPLATE_ROOT=templates', ('TEMPLATE_ROOT=' + $templateRoot)) |
- Set-Content -LiteralPath $configPath -Encoding UTF8
- & $scriptHost //nologo (Join-Path $PSScriptRoot 'init-db.vbs') $configPath
- if ($LASTEXITCODE -ne 0) { throw 'MDB initialization failed' }
-
- $png = [Convert]::FromBase64String('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+jRZkAAAAASUVORK5CYII=')
- [System.IO.File]::WriteAllBytes($imagePath, $png)
- $safe = '<html><body><h1 style="color:#112233; font-size:20px">Postcard</h1><p>See our offer.</p><img src="images/logo.png" width="1" height="1" alt="Logo" /><a href="http://example.invalid">Details</a></body></html>'
- [System.IO.File]::WriteAllText($templatePath, $safe, [System.Text.Encoding]::UTF8)
-
- & $powerShellX86 -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'import-template.ps1') -Path $templatePath -ConfigPath $configPath
- if ($LASTEXITCODE -ne 0) { throw 'Valid template import failed' }
- Remove-Item -LiteralPath $imagePath -Force
- $preview = & $powerShellX86 -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'preview-template.ps1') -TemplateId 1 -ConfigPath $configPath -OutputRoot $previewRoot
- if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $preview -PathType Leaf)) { throw 'Snapshot preview failed after source image deletion' }
- $rendered = Get-Content -LiteralPath $preview -Raw
- if ($rendered -notmatch 'image-1.png' -or $rendered -match 'cid:|file:|<script') { throw 'Preview contains an unsafe or missing image reference' }
- $savedImage = Join-Path (Split-Path -Parent $preview) 'image-1.png'
- if (([Convert]::ToBase64String([System.IO.File]::ReadAllBytes($savedImage))) -ne ([Convert]::ToBase64String($png))) {
- throw 'Preview image differs from imported snapshot'
- }
-
- foreach ($invalid in @(
- $safe.Replace('<p>See our offer.</p>', '<script>alert(1)</script>'),
- $safe.Replace('images/logo.png', '../secret.png'),
- $safe.Replace('color:#112233', 'background-image:url(file:///C:/secret)'),
- $safe.Replace('http://example.invalid', 'javascript:alert(1)')
- )) {
- [System.IO.File]::WriteAllText($templatePath, $invalid, [System.Text.Encoding]::UTF8)
- $ErrorActionPreference = 'Continue'
- $null = & $powerShellX86 -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'import-template.ps1') -Path $templatePath -ConfigPath $configPath 2>$null
- $rejected = $LASTEXITCODE -ne 0
- $ErrorActionPreference = 'Stop'
- if (-not $rejected) { throw 'Unsafe template was accepted' }
- }
- & $powerShellX86 -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'test-template-state.ps1') -ConfigPath $configPath
- if ($LASTEXITCODE -ne 0) { throw 'Invalid imports changed the template library' }
- Write-Output 'Template import, image snapshot, safe preview, and rejection checks passed'
- }
- finally {
- $resolvedWork = [System.IO.Path]::GetFullPath($workPath)
- $resolvedTemp = [System.IO.Path]::GetFullPath((Join-Path $projectRoot 'temp'))
- if ($resolvedWork.StartsWith($resolvedTemp + [System.IO.Path]::DirectorySeparatorChar,
- [StringComparison]::OrdinalIgnoreCase) -and (Test-Path -LiteralPath $resolvedWork)) {
- Remove-Item -LiteralPath $resolvedWork -Recurse -Force
- }
- }
|