Private/Helpers.ps1
|
# Default environment variable mapping for known services. # Format: service-name → ENV_VAR_NAME # Used by Import-PCSecrets when no explicit envVar is stored in the secret entry. $script:DefaultEnvVarMap = @{ 'openai' = 'OPENAI_API_KEY' 'anthropic' = 'ANTHROPIC_API_KEY' 'gemini' = 'GEMINI_API_KEY' 'azure' = 'AZURE_SPEECH_KEY' 'redmine' = 'REDMINE_API_KEY' 'google-cse' = 'GOOGLE_CSE_API_KEY' 'brave-search' = 'BRAVE_SEARCH_API_KEY' 'firecrawl' = 'FIRECRAWL_API_KEY' } function Get-PCSecretsPath { <# .SYNOPSIS Returns the resolved path to the secrets store directory and file. #> [CmdletBinding()] [OutputType([hashtable])] param() $home = if ($env:POWERCRAFT_HOME) { $env:POWERCRAFT_HOME } else { Join-Path ([Environment]::GetFolderPath('UserProfile')) '.powercraft' } return @{ Home = $home File = Join-Path $home 'secrets.json' } } function Read-PCSecretsFile { <# .SYNOPSIS Reads and parses the secrets JSON file. Returns empty hashtable if missing/invalid. #> [CmdletBinding()] [OutputType([hashtable])] param() $paths = Get-PCSecretsPath if (-not (Test-Path $paths.File)) { return @{} } try { $content = Get-Content $paths.File -Raw -ErrorAction Stop if ([string]::IsNullOrWhiteSpace($content)) { return @{} } return ($content | ConvertFrom-Json -AsHashtable -ErrorAction Stop) } catch { Write-Warning "PowerCraft.Secrets: Failed to read secrets file: $_" return @{} } } function Write-PCSecretsFile { <# .SYNOPSIS Writes the secrets hashtable to the JSON file with restrictive permissions. #> [CmdletBinding()] param( [Parameter(Mandatory)] [hashtable]$Secrets ) $paths = Get-PCSecretsPath # Ensure directory exists if (-not (Test-Path $paths.Home)) { New-Item -ItemType Directory -Path $paths.Home -Force | Out-Null } # Write JSON $Secrets | ConvertTo-Json -Depth 10 | Set-Content $paths.File -Encoding UTF8 # Set restrictive permissions Set-PCFilePermissions -Path $paths.File } function Set-PCFilePermissions { <# .SYNOPSIS Sets owner-only read/write permissions on a file. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Path ) try { if ($IsWindows) { $user = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name & icacls $Path /inheritance:r /grant "${user}:F" 2>&1 | Out-Null } else { & chmod 600 $Path 2>&1 | Out-Null } } catch { Write-Verbose "PowerCraft.Secrets: Could not set restrictive permissions: $($_.Exception.Message)" } } function Resolve-PCEnvVarName { <# .SYNOPSIS Resolves the environment variable name for a given service. Checks: explicit envVar in secret entry → default map → generated name. #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Name, [Parameter()] [hashtable]$SecretEntry ) # 1. Explicit envVar in the entry if ($SecretEntry -and $SecretEntry['envVar']) { return $SecretEntry['envVar'] } # 2. Default mapping if ($script:DefaultEnvVarMap.ContainsKey($Name)) { return $script:DefaultEnvVarMap[$Name] } # 3. Generate: service-name → SERVICE_NAME_API_KEY return ($Name.ToUpper() -replace '-', '_') + '_API_KEY' } |