$ErrorActionPreference = "Stop" $patterns = @( "DB_PASSWORD\s*=\s*(?!<)", "JWT_SECRET\s*=\s*(?!<)", "WECHAT_SECRET\s*=\s*(?!<)", "PRIVATE_KEY", "api_key\s*[:=]\s*(?!<)", "password\s*[:=]\s*(?!<)" ) $excluded = @("\.git\", "node_modules", "dist", "build") $excludedFiles = @( "V4.8.md", "scripts\dev\windows\check-secrets.ps1" ) $hits = @() $candidateFiles = @() (& git -c core.quotePath=false ls-files --cached --others --exclude-standard) | ForEach-Object { if ($_ -and (Test-Path $_ -PathType Leaf)) { $candidateFiles += (Resolve-Path $_).Path } } $candidateFiles | ForEach-Object { $path = $_ foreach ($skip in $excluded) { if ($path -match [regex]::Escape($skip)) { return } } $relativePath = Resolve-Path -Relative $path $relativePath = $relativePath.TrimStart('.', '\', '/') if ($excludedFiles -contains $relativePath) { return } $text = Get-Content -Raw -ErrorAction SilentlyContinue $path foreach ($pattern in $patterns) { if ($text -match $pattern) { $hits += $path break } } } if ($hits.Count -gt 0) { $hits | Sort-Object -Unique | ForEach-Object { Write-Host "SECRET-CHECK-HIT: $_" } throw "Potential secrets found. Please review and redact." } Write-Host "PASS: no plaintext secret pattern found."