#!/bin/bash # Bootstrap App - Secret Generation Script # This script generates cryptographically secure secrets for the Bootstrap App echo "Bootstrap App - Secret Generation Script" echo "========================================" echo "" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' WHITE='\033[1;37m' NC='\033[0m' # No Color # Function to generate hex string generate_hex_string() { local length=$1 openssl rand -hex $length 2>/dev/null || xxd -l $length -p /dev/urandom | tr -d '\n' } # Function to generate base64 string generate_base64_string() { local length=$1 openssl rand -base64 $length 2>/dev/null || dd if=/dev/urandom bs=$length count=1 2>/dev/null | base64 | tr -d '\n' } # Check if required tools are available check_dependencies() { if ! command -v openssl >/dev/null 2>&1; then if ! command -v xxd >/dev/null 2>&1; then echo -e "${RED}Error: Neither openssl nor xxd is available. Please install one of them.${NC}" exit 1 fi fi } # Generate secrets echo -e "${YELLOW}Generating cryptographically secure secrets...${NC}" echo "" check_dependencies JWT_SECRET=$(generate_base64_string 64) APP_SECRET=$(generate_hex_string 32) APP_SECRET_CODE=$(generate_hex_string 32) ENCRYPTION_KEY=$(generate_hex_string 16) # Display generated secrets echo -e "${CYAN}Generated Secrets:${NC}" echo -e "${CYAN}==================${NC}" echo "" echo -e "${WHITE}JWT_SECRET=${NC}${YELLOW}$JWT_SECRET${NC}" echo "" echo -e "${WHITE}APP_SECRET=${NC}${YELLOW}$APP_SECRET${NC}" echo "" echo -e "${WHITE}APP_SECRET_CODE=${NC}${YELLOW}$APP_SECRET_CODE${NC}" echo "" echo -e "${WHITE}ENCRYPTION_KEY=${NC}${YELLOW}$ENCRYPTION_KEY${NC}" echo "" # Check if .env file exists ENV_FILE=".env" if [ -f "$ENV_FILE" ]; then echo -e "${RED}Warning: .env file already exists!${NC}" read -p "Do you want to update it with new secrets? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then UPDATE_FILE=true else UPDATE_FILE=false echo -e "${YELLOW}Secrets generated but not written to file.${NC}" fi else read -p "Create .env file with these secrets? (Y/n): " -n 1 -r echo if [[ $REPLY =~ ^[Nn]$ ]]; then UPDATE_FILE=false echo -e "${YELLOW}Secrets generated but not written to file.${NC}" else UPDATE_FILE=true fi fi if [ "$UPDATE_FILE" = true ]; then # Create or update .env file if [ -f "$ENV_FILE" ]; then # Backup existing file BACKUP_FILE=".env.backup.$(date +%Y%m%d-%H%M%S)" cp "$ENV_FILE" "$BACKUP_FILE" echo -e "${GREEN}Backed up existing .env to $BACKUP_FILE${NC}" # Update secrets in existing file sed -i.tmp "s/^JWT_SECRET=.*/JWT_SECRET=$JWT_SECRET/" "$ENV_FILE" sed -i.tmp "s/^APP_SECRET=.*/APP_SECRET=$APP_SECRET/" "$ENV_FILE" sed -i.tmp "s/^APP_SECRET_CODE=.*/APP_SECRET_CODE=$APP_SECRET_CODE/" "$ENV_FILE" sed -i.tmp "s/^ENCRYPTION_KEY=.*/ENCRYPTION_KEY=$ENCRYPTION_KEY/" "$ENV_FILE" rm -f "$ENV_FILE.tmp" echo -e "${GREEN}Updated .env file with new secrets${NC}" else # Create new .env file from template if [ -f ".env.example" ]; then cp ".env.example" "$ENV_FILE" # Replace placeholder values with generated secrets sed -i.tmp "s/^JWT_SECRET=.*/JWT_SECRET=$JWT_SECRET/" "$ENV_FILE" sed -i.tmp "s/^APP_SECRET=.*/APP_SECRET=$APP_SECRET/" "$ENV_FILE" sed -i.tmp "s/^APP_SECRET_CODE=.*/APP_SECRET_CODE=$APP_SECRET_CODE/" "$ENV_FILE" sed -i.tmp "s/^ENCRYPTION_KEY=.*/ENCRYPTION_KEY=$ENCRYPTION_KEY/" "$ENV_FILE" rm -f "$ENV_FILE.tmp" echo -e "${GREEN}Created .env file from template with generated secrets${NC}" else # Create minimal .env file cat > "$ENV_FILE" << EOF # Bootstrap App Environment Configuration # Generated on $(date '+%Y-%m-%d %H:%M:%S') # CRITICAL SECURITY SETTINGS (REQUIRED) JWT_SECRET=$JWT_SECRET APP_SECRET=$APP_SECRET APP_SECRET_CODE=$APP_SECRET_CODE ENCRYPTION_KEY=$ENCRYPTION_KEY # CORE APPLICATION SETTINGS DB_NAME=app.db PORT=3000 CORS_ALLOWED_ORIGIN=http://localhost:5173 DEFAULT_ADMIN_PASSWORD=change-this-password EOF echo -e "${GREEN}Created minimal .env file with generated secrets${NC}" fi fi fi echo "" echo -e "${RED}Security Notes:${NC}" echo -e "${RED}===============${NC}" echo -e "${YELLOW}1. Keep these secrets secure and never commit them to version control${NC}" echo -e "${YELLOW}2. Use different secrets for each environment (dev, staging, production)${NC}" echo -e "${YELLOW}3. Rotate secrets regularly in production environments${NC}" echo -e "${YELLOW}4. The ENCRYPTION_KEY is exactly 32 characters as required for AES-256${NC}" echo -e "${YELLOW}5. Change the DEFAULT_ADMIN_PASSWORD immediately after first login${NC}" echo "" # Verify encryption key length if [ ${#ENCRYPTION_KEY} -eq 32 ]; then echo -e "${GREEN}✓ Encryption key length verified (32 characters = 32 bytes for AES-256)${NC}" else echo -e "${RED}✗ Warning: Encryption key length is incorrect! Got ${#ENCRYPTION_KEY} chars, expected 32${NC}" fi echo "" echo -e "${CYAN}Next steps:${NC}" echo -e "${WHITE}1. Review and customize the .env file if needed${NC}" echo -e "${WHITE}2. Build and run the application: go run cmd/api/main.go${NC}" echo -e "${WHITE}3. Change the default admin password on first login${NC}" echo -e "${WHITE}4. Access the API documentation at: http://localhost:3000/swagger/${NC}" echo "" echo -e "${GREEN}Happy coding! 🚀${NC}"