🔧 Add PowerShell script for Bitwarden .env synchronization
- 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.
This commit is contained in:
62
sync-env.ps1
Normal file
62
sync-env.ps1
Normal file
@@ -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
|
||||||
269
sync-env.sh
269
sync-env.sh
@@ -1,233 +1,64 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# === Bitwarden .env Sync (Advanced) ===
|
# Simple Bitwarden .env Sync
|
||||||
|
# Works on Mac and Windows (Git Bash)
|
||||||
|
|
||||||
# Configuration
|
echo "=== Bitwarden .env Sync ==="
|
||||||
TARGET_DIR=""
|
|
||||||
SESSION_FILE="$HOME/.bw-session"
|
|
||||||
DEBUG=false
|
|
||||||
|
|
||||||
# Parse arguments
|
# Check if bw is installed
|
||||||
for arg in "$@"; do
|
if ! command -v bw &> /dev/null; then
|
||||||
case $arg in
|
echo "Error: Bitwarden CLI (bw) is not installed"
|
||||||
--debug)
|
echo "Install it from: https://bitwarden.com/help/cli/"
|
||||||
DEBUG=true
|
exit 1
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# 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)"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Logging functions
|
# Check if logged in
|
||||||
log_info() {
|
STATUS=$(bw status | grep -o '"status":"[^"]*' | cut -d'"' -f4)
|
||||||
echo "[INFO] $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
log_debug() {
|
if [ "$STATUS" = "unauthenticated" ]; then
|
||||||
if [[ "$DEBUG" == "true" ]]; then
|
echo "Please login to Bitwarden:"
|
||||||
echo "[DEBUG] $1"
|
bw login
|
||||||
fi
|
STATUS="locked"
|
||||||
}
|
fi
|
||||||
|
|
||||||
log_error() {
|
# Unlock vault if needed
|
||||||
echo "[ERROR] $1" >&2
|
if [ "$STATUS" = "locked" ]; then
|
||||||
}
|
echo "Unlocking vault..."
|
||||||
|
export BW_SESSION=$(bw unlock --raw)
|
||||||
# Check dependencies
|
if [ $? -ne 0 ]; then
|
||||||
check_dependencies() {
|
echo "Error: Failed to unlock vault"
|
||||||
log_debug "Checking dependencies..."
|
|
||||||
|
|
||||||
if ! command -v bw &> /dev/null; then
|
|
||||||
log_error "Bitwarden CLI (bw) is not installed"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
log_debug "bw found at: $(which bw)"
|
fi
|
||||||
|
|
||||||
if ! command -v jq &> /dev/null; then
|
|
||||||
log_error "jq is not installed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
log_debug "jq found at: $(which jq)"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Authenticate with Bitwarden
|
# Sync with Bitwarden
|
||||||
authenticate_bitwarden() {
|
echo "Syncing with Bitwarden..."
|
||||||
log_debug "Starting Bitwarden authentication..."
|
bw sync
|
||||||
|
|
||||||
# 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 environment variables
|
# CHANGE THIS to your Bitwarden item name
|
||||||
sync_env_vars() {
|
ITEM_NAME="portfolio-env"
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main execution
|
echo "Fetching environment variables..."
|
||||||
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 ==="
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run main function
|
# Get the item from Bitwarden
|
||||||
main
|
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!"
|
||||||
Reference in New Issue
Block a user