Private/Get-DhExportLibraries.ps1
|
function Get-DhExportLibraries { <# .SYNOPSIS The XLSX / PDF export libraries: the ONE place their versions, CDN URLs and SRI hashes are listed (v2.2.0). .DESCRIPTION Order matters: jsPDF must load before AutoTable, which patches it. Upgrading a library means changing the entry here and the file in DashHtml\Vendor\ (see Vendor\README.md); the SRI test pins both. #> [CmdletBinding()] param() @( [ordered]@{ Key = 'xlsx'; File = 'xlsx.full.min.js'; Version = '0.18.5' Url = 'https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js' Sri = 'sha384-vtjasyidUo0kW94K5MXDXntzOJpQgBKXmE7e2Ga4LG0skTTLeBi97eFAXsqewJjw' } [ordered]@{ Key = 'jspdf'; File = 'jspdf.umd.min.js'; Version = '2.5.1' Url = 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js' Sri = 'sha384-JcnsjUPPylna1s1fvi1u12X5qjY5OL56iySh75FdtrwhO/SWXgMjoVqcKyIIWOLk' } [ordered]@{ Key = 'autotable'; File = 'jspdf.plugin.autotable.min.js'; Version = '3.8.2' Url = 'https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.8.2/jspdf.plugin.autotable.min.js' Sri = 'sha384-fCAW/rDWORTbQXSiB7mOg0QtQ5c+r0f544y6XoKjuVva0nMBlCpNUjiFeG5iMdS3' } ) } function Get-DhExportLibraryConfigJson { <# .SYNOPSIS JSON for the runtime's EXPORT_LIBS: the mode plus, for Cdn, where to fetch each library and the hash it must match. #> [CmdletBinding()] [OutputType([string])] param([Parameter(Mandatory)] [ValidateSet('cdn','embed','none')] [string] $Mode) $libs = (Get-DhExportLibraries | ForEach-Object { "$(ConvertTo-DhJsonString $_.Key):{`"url`":$(ConvertTo-DhJsonString $_.Url),`"sri`":$(ConvertTo-DhJsonString $_.Sri)}" }) -join ',' "{`"mode`":$(ConvertTo-DhJsonString $Mode),`"libs`":{$libs}}" } function Get-DhEmbeddedExportLibraries { <# .SYNOPSIS <script> elements that inline the vendored libraries (-ExportLibraries Embed). .DESCRIPTION Each file is checked against its pinned SRI hash before it is embedded, so Embed always runs exactly the code Cdn would load, and a tampered or half-written file is refused rather than shipped. Each library gets its own <script> element and is inlined UNCHANGED. Rewriting minified code to escape markup is not safe (inside a regex literal, '<\s' no longer means '<s'), so instead the two sequences that could end or derail an inline script are refused: - '</script' closes the element early; - '<!--' together with '<script' in the same element puts the HTML parser in a state where '</script>' no longer closes it. The pinned versions contain neither combination. #> [CmdletBinding()] [OutputType([string])] param() $vendor = Join-Path (Split-Path $PSScriptRoot -Parent) 'Vendor' $sb = [System.Text.StringBuilder]::new() $total = 0 foreach ($lib in Get-DhExportLibraries) { $path = Join-Path $vendor $lib.File if (-not (Test-Path -LiteralPath $path)) { throw "Export-DhDashboard -ExportLibraries Embed: '$($lib.File)' is missing from $vendor. Reinstall the module, or use -ExportLibraries Cdn." } $bytes = [System.IO.File]::ReadAllBytes($path) $hash = 'sha384-' + [System.Convert]::ToBase64String([System.Security.Cryptography.SHA384]::HashData($bytes)) if ($hash -ne $lib.Sri) { throw "Export-DhDashboard -ExportLibraries Embed: $path does not match its pinned hash ($($lib.Key) $($lib.Version)). Refusing to embed it." } $code = [System.Text.Encoding]::UTF8.GetString($bytes) if ($code -match '(?i)</script' -or ($code.Contains('<!--') -and $code -match '(?i)<script')) { throw "Export-DhDashboard -ExportLibraries Embed: $($lib.File) contains markup that would break out of an inline <script>. Refusing to embed it." } $total += $bytes.Length [void]$sb.AppendLine(" <script data-dh-lib=`"$($lib.Key)`" data-dh-version=`"$($lib.Version)`">") [void]$sb.AppendLine($code) [void]$sb.AppendLine(' </script>') if ($lib.Key -eq 'jspdf') { # jsPDF 2.x UMD exposes window.jspdf.jsPDF; AutoTable looks for window.jsPDF [void]$sb.AppendLine(' <script>if(window.jspdf&&window.jspdf.jsPDF&&!window.jsPDF){window.jsPDF=window.jspdf.jsPDF;}</script>') } } # Verbose, not a warning: Embed is an explicit choice, and a warning on every # run would teach people to ignore warnings. The size is in the help text. Write-Verbose ("Export-DhDashboard: -ExportLibraries Embed adds {0:N1} MB of XLSX/PDF library code to the report." -f ($total / 1MB)) $sb.ToString() } |