HackerOne.psm1
function Set-H1ApiKey { param ( [Parameter(Mandatory)][string]$Username, [Parameter(Mandatory)][string]$ApiToken ) $secureToken = ConvertTo-SecureString $ApiToken -AsPlainText -Force $secureBytes = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureToken) $plainToken = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($secureBytes) $encrypted = ConvertTo-SecureString $plainToken -AsPlainText -Force | ConvertFrom-SecureString $creds = @{ Username = $Username Token = $encrypted } $path = Join-Path $HOME ".h1navigator" if (-not (Test-Path $path)) { New-Item -ItemType Directory -Path $path | Out-Null } $creds | ConvertTo-Json | Set-Content -Path (Join-Path $path "creds.json") Write-Host "✅ HackerOne API credentials stored securely at `$HOME\.h1navigator\creds.json" } function Get-H1ApiKey { $path = Join-Path $HOME ".h1navigator\creds.json" if (-not (Test-Path $path)) { throw "❌ API credentials not found. Please run Set-H1ApiKey first." } $json = Get-Content -Raw -Path $path | ConvertFrom-Json $token = $json.Token | ConvertTo-SecureString $plainToken = [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR( [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($token) ) return @{ Username = $json.Username Token = $plainToken } } function Get-H1Programs { param ( [switch]$ForceRefresh ) $cachePath = Join-Path $HOME ".h1navigator\programs.json" if (-not $ForceRefresh -and (Test-Path $cachePath)) { try { $json = Get-Content -Raw -Path $cachePath | ConvertFrom-Json return $json } catch { Write-Warning "⚠️ Failed to read local cache, refetching..." } } $creds = Get-H1ApiKey $headers = @{ Authorization = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("$($creds.Username):$($creds.Token)")) } $allPrograms = @() $page = 1 $hasMore = $true while ($hasMore) { $url = "https://api.hackerone.com/v1/hackers/programs?page[number]=$page" try { $response = Invoke-RestMethod -Uri $url -Headers $headers $batch = $response.data | ForEach-Object { [PSCustomObject]@{ Name = $_.attributes.name Handle = $_.attributes.handle OffersBounties = $_.attributes.offers_bounties State = $_.attributes.state SubmissionState = $_.attributes.submission_state PolicySnippet = ($_.attributes.policy -split "`n")[0] } } $allPrograms += $batch $page += 1 $hasMore = $response.links.next -ne $null } catch { throw "❌ Failed on page $page : $_" } } # Save to disk if (-not (Test-Path (Split-Path $cachePath))) { New-Item -ItemType Directory -Path (Split-Path $cachePath) -Force | Out-Null } $allPrograms | ConvertTo-Json -Depth 3 | Set-Content -Path $cachePath -Encoding UTF8 return $allPrograms } function Search-H1Programs { [CmdletBinding()] param ( [string]$Keyword, [switch]$BountyOnly, [ValidateSet('open','closed')] [string]$SubmissionState, [switch]$Names, [switch]$ForceRefresh ) $programs = Get-H1Programs -ForceRefresh:$ForceRefresh if ($Keyword) { $programs = $programs | Where-Object { $_.Name -match $Keyword -or $_.PolicySnippet -match $Keyword } } if ($BountyOnly) { $programs = $programs | Where-Object { $_.OffersBounties } } if ($PSBoundParameters.ContainsKey('SubmissionState')) { $programs = $programs | Where-Object { $_.SubmissionState -ieq $SubmissionState } } if ($Names) { return $programs | Select-Object -ExpandProperty Name } return $programs } function Get-H1Policy { [CmdletBinding()] param ( [Parameter(Mandatory)][string]$Handle ) $url = "https://hackerone.com/$Handle" Write-Host "🌐 Opening $url ..." Start-Process $url } |