diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..2a17508 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,46 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/powershell +{ + "name": "PowerShell", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/powershell:lts-debian-11", + "features": { + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": "true", + "username": "vscode", + "upgradePackages": "false", + "nonFreePackages": "true" + }, + "ghcr.io/devcontainers/features/powershell:1": { + "version": "latest" + } + }, + + "postCreateCommand": "sudo chsh vscode -s \"$(which pwsh)\"", + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "terminal.integrated.defaultProfile.linux": "pwsh" + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-vscode.powershell", + "github.vscode-github-actions", + "VisualStudioExptTeam.vscodeintellicode", + "GitHub.copilot", + "GitHub.copilot-chat" + ] + } + } + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.github/removate.json b/.github/removate.json new file mode 100644 index 0000000..a96c48e --- /dev/null +++ b/.github/removate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "github>ikifar2012/.github" + ] + } \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..1872664 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,39 @@ +name: Publish PowerShell Module + +on: + release: + types: ["published"] + +jobs: + publish-to-gallery: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Publish + env: + NUGET_KEY: ${{ secrets.NUGET_KEY }} + shell: pwsh + run: | + $modulePath = Join-Path $env:GITHUB_WORKSPACE "ps-copyid" + if (-not (Test-Path $modulePath)) { + throw "Module path not found: $modulePath" + } + + try { + Write-Host "Publishing module from: $modulePath" + Publish-Module -Path $modulePath -NuGetApiKey $env:NUGET_KEY -Repository PSGallery -ErrorAction Stop + + # Verify publish was successful + $moduleInfo = Test-ModuleManifest -Path (Join-Path $modulePath "ps-copyid.psd1") + $publishedModule = Find-Module -Name $moduleInfo.Name -RequiredVersion $moduleInfo.Version + if ($publishedModule) { + Write-Host "Successfully published $($moduleInfo.Name) version $($moduleInfo.Version)" + } else { + throw "Module verification failed after publish" + } + } + catch { + throw "Failed to publish module: $_" + } \ No newline at end of file diff --git a/ps-copyid.psm1 b/ps-copyid.psm1 deleted file mode 100644 index 30bf5db..0000000 --- a/ps-copyid.psm1 +++ /dev/null @@ -1,31 +0,0 @@ -function Copy-ID { - param ( - [Parameter(Mandatory=$true)] - [String]$hostname, - $id= $null - ) - if ($null -eq $id) { - $sshdir="$env:USERPROFILE\.ssh" - $rsa=$(Test-Path -Path "$sshdir\id_rsa.pub") - $ecdsa=$(Test-Path -Path "$sshdir\id_ecdsa.pub") - $ed25519=$(Test-Path -Path "$sshdir\id_ed25519.pub") - Write-Output "Testing Keys..." - if ($ed25519 -eq "True") { - Write-Output "Found ED25519 Key, Installing..." - $id= "$sshdir\id_ed25519.pub" - } elseif ($ecdsa -eq "True") { - Write-Output "Found ECDSA Key, Installing..." - $id= "$sshdir\id_ecdsa.pub" - } elseif ($rsa -eq "True") { - Write-Output "Found RSA Key, Installing..." - $id= "$sshdir\id_rsa.pub" - } else { - Write-Warning "No keys found" - $id= Read-Host -Prompt "Please manually enter the path to your public key" - } - } else { - Write-Output "Installing Key..." - } - Get-Content $id | ssh $hostname "mkdir .ssh 2>/dev/null; chmod 700 .ssh 2>/dev/null; touch .ssh/authorized_keys 2>/dev/null; chmod 644 .ssh/authorized_keys 2>/dev/null; cat >> .ssh/authorized_keys" -} -Export-ModuleMember -Function * -Alias * \ No newline at end of file diff --git a/ps-copyid.psd1 b/ps-copyid/ps-copyid.psd1 similarity index 100% rename from ps-copyid.psd1 rename to ps-copyid/ps-copyid.psd1 diff --git a/ps-copyid/ps-copyid.psm1 b/ps-copyid/ps-copyid.psm1 new file mode 100644 index 0000000..17968ad --- /dev/null +++ b/ps-copyid/ps-copyid.psm1 @@ -0,0 +1,69 @@ +function Copy-ID { + [CmdletBinding()] + param ( + [Parameter(Mandatory=$true)] + [String]$hostname, + [Parameter(Mandatory=$false)] + [String]$id + ) + + # If no key specified, find existing keys + if (-not $id) { + $sshdir = Join-Path $HOME '.ssh' + Write-Host "Testing Keys..." + + # Check for keys in preference order + $keyTypes = @( + @{ Type = "ED25519"; Path = Join-Path $sshdir 'id_ed25519.pub' }, + @{ Type = "ECDSA"; Path = Join-Path $sshdir 'id_ecdsa.pub' }, + @{ Type = "RSA"; Path = Join-Path $sshdir 'id_rsa.pub' } + ) + + foreach ($key in $keyTypes) { + if (Test-Path -Path $key.Path) { + Write-Host "Found $($key.Type) Key, Installing..." + $id = $key.Path + break + } + } + + if (-not $id) { + Write-Warning "No keys found" + $id = Read-Host -Prompt "Please manually enter the path to your public key" + } + } + else { + Write-Host "Installing Key..." + } + + # Verify key exists + if (-not (Test-Path -Path $id)) { + throw "Could not find public key file: $id" + } + + # Verify key format + $keyContent = Get-Content $id + if (-not ($keyContent -match '^(ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521)\s+[A-Za-z0-9+/]+[=]{0,3}\s+.*$')) { + throw "Invalid SSH public key format in file: $id" + } + + # The critical part: Remote commands to handle SSH directory and permissions + $remoteCommands = @' + mkdir -p ~/.ssh + chmod 700 ~/.ssh + touch ~/.ssh/authorized_keys + chmod 600 ~/.ssh/authorized_keys + cat >> ~/.ssh/authorized_keys +'@ + + Get-Content $id | ssh $hostname $remoteCommands + # Check for success + if ($?) { + Write-Host "Key Installed Successfully" + } + else { + Write-Warning "Key Installation Failed" + } +} + +Export-ModuleMember -Function Copy-ID \ No newline at end of file