# 浏览器来源为可选项:缺失或留空时保持宽松策略,显式配置时校验。 . (Join-Path $PSScriptRoot "Initialize-PublicApiBaseUrl.ps1") function Initialize-SecurityOrigin { param([Parameter(Mandatory = $true)][string]$Path) if (-not (Test-Path $Path)) { throw "Environment file not found: $Path" } $content = Get-Content $Path -Raw -Encoding UTF8 if ($null -eq $content) { $content = "" } $current = Get-PublicEnvValue $content "CONFIG_SECURITY_ORIGIN" if (-not $current) { Write-Host " [OK] Browser origin is not configured; backend allows all origins" -ForegroundColor Green return } # The legacy sample value was not a user-selected allowlist. Clear it on non-local upgrades. if ($current -eq "http://127.0.0.1,http://localhost") { $apiUrl = Get-PublicEnvValue $content "CONFIG_PUBLIC_API_BASE_URL" $normalizedApiUrl = ConvertTo-PublicApiBaseUrl $apiUrl if ($normalizedApiUrl) { $derived = ([Uri]$normalizedApiUrl).GetLeftPart([UriPartial]::Authority) if ($derived -notin @('http://127.0.0.1', 'http://localhost')) { $content = Set-PublicEnvValue $content "CONFIG_SECURITY_ORIGIN" "" [System.IO.File]::WriteAllText( (Resolve-Path $Path), $content, [System.Text.UTF8Encoding]::new($false) ) Write-Host " [OK] Cleared legacy browser-origin sample; backend allows all origins" -ForegroundColor Green return } } } if ($current.StartsWith(',') -or $current.EndsWith(',') -or $current.Contains(',,')) { throw "CONFIG_SECURITY_ORIGIN contains an empty origin" } foreach ($value in $current.Split(',')) { $origin = $value.Trim() $uri = $null if (-not [Uri]::TryCreate($origin, [UriKind]::Absolute, [ref]$uri) -or $uri.Scheme -notin @('http', 'https') -or $uri.UserInfo -or $uri.Query -or $uri.Fragment -or $uri.AbsolutePath -ne '/' -or -not $uri.Host) { throw "CONFIG_SECURITY_ORIGIN must contain only http(s) origins without paths or wildcards" } } }