From 6be2feb8dd45c8405fa262927900a04c30b22f4b Mon Sep 17 00:00:00 2001 From: denshooter Date: Tue, 16 Sep 2025 00:00:07 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Add=20PowerShell=20script=20for?= =?UTF-8?q?=20Bitwarden=20.env=20synchronization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Introduced `sync-env.ps1` to facilitate the synchronization of environment variables from Bitwarden on Windows. - Implemented checks for Bitwarden CLI installation and authentication status. - Added functionality to fetch environment variables from a specified Bitwarden item and create/update a `.env` file. - Enhanced user feedback with clear error messages and success confirmations. ✅ This script streamlines the management of environment variables by integrating with Bitwarden, ensuring secure and efficient updates. --- sync-env.ps1 | 62 ++++++++++++ sync-env.sh | 269 ++++++++++----------------------------------------- 2 files changed, 112 insertions(+), 219 deletions(-) create mode 100644 sync-env.ps1 diff --git a/sync-env.ps1 b/sync-env.ps1 new file mode 100644 index 0000000..c1d647b --- /dev/null +++ b/sync-env.ps1 @@ -0,0 +1,62 @@ +# Simple Bitwarden .env Sync for Windows +# Run with: powershell -ExecutionPolicy Bypass -File sync-env.ps1 + +Write-Host "=== Bitwarden .env Sync ===" -ForegroundColor Cyan + +# Check if bw is installed +if (!(Get-Command bw -ErrorAction SilentlyContinue)) { + Write-Host "Error: Bitwarden CLI (bw) is not installed" -ForegroundColor Red + Write-Host "Install it from: https://bitwarden.com/help/cli/" + exit 1 +} + +# Check status +$status = bw status | ConvertFrom-Json + +if ($status.status -eq "unauthenticated") { + Write-Host "Please login to Bitwarden:" + bw login + $status = bw status | ConvertFrom-Json +} + +# Unlock if needed +if ($status.status -eq "locked") { + Write-Host "Unlocking vault..." + $env:BW_SESSION = bw unlock --raw + if ($LASTEXITCODE -ne 0) { + Write-Host "Error: Failed to unlock vault" -ForegroundColor Red + exit 1 + } +} + +# Sync +Write-Host "Syncing with Bitwarden..." +bw sync | Out-Null + +# CHANGE THIS to your Bitwarden item name +$itemName = "portfolio-env" + +Write-Host "Fetching environment variables..." + +# Get item +$item = bw get item $itemName 2>$null | ConvertFrom-Json + +if (!$item) { + Write-Host "Error: Could not find item '$itemName' in Bitwarden" -ForegroundColor Red + Write-Host "Make sure you have an item with this exact name in your vault" + exit 1 +} + +# Get notes +$notes = $item.notes + +if (!$notes) { + Write-Host "Error: No notes found in item '$itemName'" -ForegroundColor Red + Write-Host "Add your environment variables to the notes field" + exit 1 +} + +# Create .env file +$notes | Out-File -FilePath ".env" -Encoding UTF8 -NoNewline + +Write-Host "✓ Created .env file successfully!" -ForegroundColor Green \ No newline at end of file diff --git a/sync-env.sh b/sync-env.sh index 686adb2..e76f119 100755 --- a/sync-env.sh +++ b/sync-env.sh @@ -1,233 +1,64 @@ #!/bin/bash -# === Bitwarden .env Sync (Advanced) === +# Simple Bitwarden .env Sync +# Works on Mac and Windows (Git Bash) -# Configuration -TARGET_DIR="" -SESSION_FILE="$HOME/.bw-session" -DEBUG=false +echo "=== Bitwarden .env Sync ===" -# Parse arguments -for arg in "$@"; do - case $arg in - --debug) - DEBUG=true - ;; - *) - # If not a flag, treat as target directory - if [[ -z "$TARGET_DIR" ]] && [[ "$arg" != --* ]]; then - TARGET_DIR="$arg" - fi - ;; - esac -done - -# Set default target directory if not specified -if [[ -z "$TARGET_DIR" ]]; then - TARGET_DIR="$(pwd)" +# Check if bw is installed +if ! command -v bw &> /dev/null; then + echo "Error: Bitwarden CLI (bw) is not installed" + echo "Install it from: https://bitwarden.com/help/cli/" + exit 1 fi -# Logging functions -log_info() { - echo "[INFO] $1" -} +# Check if logged in +STATUS=$(bw status | grep -o '"status":"[^"]*' | cut -d'"' -f4) -log_debug() { - if [[ "$DEBUG" == "true" ]]; then - echo "[DEBUG] $1" - fi -} +if [ "$STATUS" = "unauthenticated" ]; then + echo "Please login to Bitwarden:" + bw login + STATUS="locked" +fi -log_error() { - echo "[ERROR] $1" >&2 -} - -# Check dependencies -check_dependencies() { - log_debug "Checking dependencies..." - - if ! command -v bw &> /dev/null; then - log_error "Bitwarden CLI (bw) is not installed" +# Unlock vault if needed +if [ "$STATUS" = "locked" ]; then + echo "Unlocking vault..." + export BW_SESSION=$(bw unlock --raw) + if [ $? -ne 0 ]; then + echo "Error: Failed to unlock vault" exit 1 fi - log_debug "bw found at: $(which bw)" - - if ! command -v jq &> /dev/null; then - log_error "jq is not installed" - exit 1 - fi - log_debug "jq found at: $(which jq)" -} +fi -# Authenticate with Bitwarden -authenticate_bitwarden() { - log_debug "Starting Bitwarden authentication..." - - # Check if we have a valid session - if [[ -f "$SESSION_FILE" ]]; then - log_debug "Session file found, loading session..." - export BW_SESSION=$(cat "$SESSION_FILE") - - # Test if session is valid - if bw status --session "$BW_SESSION" 2>/dev/null | jq -e '.status == "unlocked"' &>/dev/null; then - log_debug "Session is valid and vault is unlocked" - return 0 - else - log_debug "Session is invalid or vault is locked" - rm -f "$SESSION_FILE" - fi - else - log_debug "Session file does not exist" - fi - - # Check login status - STATUS=$(bw status | jq -r '.status') - log_debug "Bitwarden status: $STATUS" - - case "$STATUS" in - "unauthenticated") - log_info "Not logged in to Bitwarden. Please login:" - bw login - if [[ $? -ne 0 ]]; then - log_error "Login failed" - exit 1 - fi - # After login, we need to unlock - STATUS="locked" - ;; - esac - - # Handle locked vault - if [[ "$STATUS" == "locked" ]]; then - log_info "Vault is locked. Unlocking..." - - # Unlock and capture the session key - SESSION_OUTPUT=$(bw unlock --raw) - if [[ $? -ne 0 ]]; then - log_error "Failed to unlock vault" - exit 1 - fi - - # Save session to file and export - echo "$SESSION_OUTPUT" > "$SESSION_FILE" - export BW_SESSION="$SESSION_OUTPUT" - log_debug "Vault unlocked and session saved" - - elif [[ "$STATUS" == "unlocked" ]]; then - # Vault is already unlocked but we don't have the session - log_info "Vault is already unlocked but session not found. Please unlock again:" - - SESSION_OUTPUT=$(bw unlock --raw) - if [[ $? -ne 0 ]]; then - log_error "Failed to get session" - exit 1 - fi - - echo "$SESSION_OUTPUT" > "$SESSION_FILE" - export BW_SESSION="$SESSION_OUTPUT" - log_debug "Session retrieved and saved" - fi - - # Final verification - if ! bw status --session "$BW_SESSION" 2>/dev/null | jq -e '.status == "unlocked"' &>/dev/null; then - log_error "Failed to authenticate with Bitwarden" - exit 1 - fi - - log_info "Successfully authenticated with Bitwarden" -} +# Sync with Bitwarden +echo "Syncing with Bitwarden..." +bw sync -# Sync environment variables -sync_env_vars() { - log_info "Starting .env sync to: $TARGET_DIR" - - # Ensure BW_SESSION is set - if [[ -z "$BW_SESSION" ]]; then - log_error "No Bitwarden session available" - exit 1 - fi - - # Sync with Bitwarden to get latest data - log_info "Syncing with Bitwarden to get latest data..." - if bw sync --session "$BW_SESSION" &>/dev/null; then - log_debug "Successfully synced with Bitwarden" - else - log_error "Failed to sync with Bitwarden" - exit 1 - fi - - # Create .env file path - ENV_FILE="$TARGET_DIR/.env" - - # Backup existing .env if it exists - if [[ -f "$ENV_FILE" ]]; then - cp "$ENV_FILE" "${ENV_FILE}.backup" - log_debug "Backed up existing .env to .env.backup" - fi - - # Search for items with .env in notes or custom fields - # Adjust the search query based on how you store your env vars - log_info "Fetching environment variables from Bitwarden..." - - # Example: Get a specific item by name (adjust based on your setup) - # You might want to search by folder, collection, or specific naming convention - ITEM_NAME="portfolio-env" # Adjust this to your item name - - ITEM=$(bw get item "$ITEM_NAME" --session "$BW_SESSION" 2>/dev/null) - - if [[ -z "$ITEM" ]]; then - log_error "Could not find item '$ITEM_NAME' in Bitwarden" - log_info "Make sure you have an item named '$ITEM_NAME' with your environment variables" - exit 1 - fi - - # Extract notes (assuming env vars are in notes field) - NOTES=$(echo "$ITEM" | jq -r '.notes // empty') - - if [[ -z "$NOTES" ]]; then - # Try custom fields if notes are empty - log_debug "Notes empty, checking custom fields..." - - # Extract all custom fields and format as KEY=VALUE - echo "$ITEM" | jq -r '.fields[]? | select(.type == 0) | "\(.name)=\(.value)"' > "$ENV_FILE" - - if [[ ! -s "$ENV_FILE" ]]; then - log_error "No environment variables found in item '$ITEM_NAME'" - exit 1 - fi - else - # Write notes directly to .env file - echo "$NOTES" > "$ENV_FILE" - fi - - # Validate .env file - if [[ -f "$ENV_FILE" ]] && [[ -s "$ENV_FILE" ]]; then - log_info "Successfully created .env file at: $ENV_FILE" - log_debug "Environment variables written:" - if [[ "$DEBUG" == "true" ]]; then - # Show keys only, not values for security - grep -E '^[A-Z_]+=' "$ENV_FILE" | cut -d'=' -f1 | while read -r key; do - echo " - $key" - done - fi - else - log_error "Failed to create .env file or file is empty" - exit 1 - fi -} +# CHANGE THIS to your Bitwarden item name +ITEM_NAME="portfolio-env" -# Main execution -main() { - log_info "=== Bitwarden .env Sync (Advanced) ===" - log_info "Target directory: $TARGET_DIR" - log_debug "Session file: $SESSION_FILE" - - check_dependencies - authenticate_bitwarden - sync_env_vars - - log_info "=== Sync completed successfully ===" -} +echo "Fetching environment variables..." -# Run main function -main \ No newline at end of file +# Get the item from Bitwarden +ITEM=$(bw get item "$ITEM_NAME" 2>/dev/null) + +if [ -z "$ITEM" ]; then + echo "Error: Could not find item '$ITEM_NAME' in Bitwarden" + echo "Make sure you have an item with this exact name in your vault" + exit 1 +fi + +# Extract notes (where env vars should be stored) +NOTES=$(echo "$ITEM" | grep -o '"notes":"[^"]*' | cut -d'"' -f4 | sed 's/\\n/\n/g') + +if [ -z "$NOTES" ]; then + echo "Error: No notes found in item '$ITEM_NAME'" + echo "Add your environment variables to the notes field" + exit 1 +fi + +# Create .env file +echo "$NOTES" > .env + +echo "✓ Created .env file successfully!" \ No newline at end of file