Files
Git-Skill/.cursor/skills/git-init/scripts/inject-credential.ps1
T
2026-08-20 23:42:02 +08:00

113 lines
3.1 KiB
PowerShell

# Agent-safe: decrypt the local token and feed it to Git Credential Manager.
# Never prints the token. Never writes it to a file.
param(
[Parameter(Mandatory = $true)]
[string]$RemoteUrl
)
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot 'common.ps1')
$gitProfile = Get-GitSkillsProfile
if ($null -eq $gitProfile) {
Write-StatusLine -Key 'status' -Value 'failed'
Write-StatusLine -Key 'reason' -Value 'profile_missing'
exit 1
}
$username = ([string]$gitProfile.gitUsername).Trim()
if ([string]::IsNullOrWhiteSpace($username)) {
Write-StatusLine -Key 'status' -Value 'failed'
Write-StatusLine -Key 'reason' -Value 'git_username_missing'
exit 1
}
if ($username -match "[\r\n]") {
Write-StatusLine -Key 'status' -Value 'failed'
Write-StatusLine -Key 'reason' -Value 'git_username_invalid'
exit 1
}
if (-not (Test-Path -LiteralPath $script:TokenPath)) {
Write-StatusLine -Key 'status' -Value 'failed'
Write-StatusLine -Key 'reason' -Value 'token_missing'
exit 1
}
$parsed = Parse-GitRemoteUrl -RemoteUrl $RemoteUrl
$hostName = [string]$parsed.CredentialHost
if ([string]::IsNullOrWhiteSpace($hostName)) {
$hostName = [string]$parsed.Host
}
if ([string]::IsNullOrWhiteSpace($hostName)) {
Write-StatusLine -Key 'status' -Value 'failed'
Write-StatusLine -Key 'reason' -Value 'host_parse_failed'
exit 1
}
$credProtocol = 'https'
if ([string]$parsed.Protocol -eq 'http') {
$credProtocol = 'http'
}
$token = $null
$payload = $null
try {
$data = [System.IO.File]::ReadAllBytes($script:TokenPath)
$token = Unprotect-SecretBytes -Data $data
if ([string]::IsNullOrWhiteSpace($token)) {
Write-StatusLine -Key 'status' -Value 'failed'
Write-StatusLine -Key 'reason' -Value 'token_invalid'
exit 1
}
$payload = @"
protocol=$credProtocol
host=$hostName
username=$username
password=$token
"@
$psi = New-Object System.Diagnostics.ProcessStartInfo
$psi.FileName = 'git'
$psi.Arguments = 'credential approve'
$psi.UseShellExecute = $false
$psi.RedirectStandardInput = $true
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
$psi.CreateNoWindow = $true
$proc = New-Object System.Diagnostics.Process
$proc.StartInfo = $psi
[void]$proc.Start()
foreach ($line in ($payload -split "`r?`n")) {
$proc.StandardInput.WriteLine($line)
}
$proc.StandardInput.Close()
$null = $proc.StandardOutput.ReadToEnd()
$null = $proc.StandardError.ReadToEnd()
$proc.WaitForExit()
if ($proc.ExitCode -ne 0) {
Write-StatusLine -Key 'status' -Value 'failed'
Write-StatusLine -Key 'reason' -Value 'git_credential_approve_failed'
exit 1
}
}
catch {
Write-StatusLine -Key 'status' -Value 'failed'
Write-StatusLine -Key 'reason' -Value 'inject_error'
exit 1
}
finally {
$token = $null
$payload = $null
$data = $null
}
Write-StatusLine -Key 'status' -Value 'injected'
Write-StatusLine -Key 'host' -Value $hostName
Write-StatusLine -Key 'protocol' -Value $credProtocol
Write-StatusLine -Key 'username' -Value $username
Write-Output 'token=hidden'