#!/bin/bash # ============================================ # Wordly.art - Gestion des cles API # ============================================ # Ajouter, modifier ou supprimer des cles API # Usage: bash scripts/manage-keys.sh # ============================================ ENV_FILE=".env" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' if [ ! -f "$ENV_FILE" ]; then echo -e "${RED}.env non trouve. Lance d'abord: bash scripts/setup-env.sh${NC}" exit 1 fi get_env() { grep "^${1}=" "$ENV_FILE" 2>/dev/null | cut -d'=' -f2- || echo "" } set_env() { local key="$1" value="$2" if grep -q "^${key}=" "$ENV_FILE"; then sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE" else echo "${key}=${value}" >> "$ENV_FILE" fi } clear_env() { local key="$1" sed -i "s|^${key}=.*|${key}=|" "$ENV_FILE" } show_status() { local name="$1" key="$2" local value=$(get_env "$key") local enabled_key="${3:-}" local enabled="" if [ -n "$enabled_key" ]; then enabled=$(get_env "$enabled_key") fi if [ -z "$value" ]; then echo -e " ${RED}--${NC} ${name}: ${YELLOW}non configure${NC}" elif [ -n "$enabled_key" ] && [ "$enabled" != "true" ]; then local masked="${value:0:8}...${value: -4}" echo -e " ${YELLOW}!!${NC} ${name}: ${masked} ${YELLOW}(desactive)${NC}" else local masked="${value:0:8}...${value: -4}" echo -e " ${GREEN}OK${NC} ${name}: ${masked}" fi } ask_key() { local name="$1" key="$2" local current=$(get_env "$key") echo "" if [ -n "$current" ]; then local masked="${current:0:8}...${current: -4}" echo -e " Actuel: ${masked}" fi echo -ne " ${YELLOW}Nouvelle valeur (Enter = garder, 'x' = effacer):${NC} " stty -echo 2>/dev/null || true read -r value stty echo 2>/dev/null || true echo "" if [ "$value" = "x" ]; then clear_env "$key" echo -e " ${RED}Supprime${NC}" elif [ -n "$value" ]; then set_env "$key" "$value" echo -e " ${GREEN}Mis a jour${NC}" else echo -e " ${CYAN}Inchange${NC}" fi } ask_value() { local name="$1" key="$2" default="$3" local current=$(get_env "$key") echo -ne " ${YELLOW}${name}${NC} [${current:-$default}]: " read -r value if [ -n "$value" ]; then set_env "$key" "$value" elif [ -z "$current" ] && [ -n "$default" ]; then set_env "$key" "$default" fi } restart_hint() { echo "" echo -e " ${YELLOW}Redemarre pour appliquer: docker compose restart backend${NC}" } # =========================================== # Menu # =========================================== while true; do echo "" echo -e "${CYAN}${BOLD}=========================================${NC}" echo -e "${CYAN}${BOLD} Wordly - Gestion des cles API${NC}" echo -e "${CYAN}${BOLD}=========================================${NC}" echo "" echo -e " Service actif: ${BOLD}$(get_env TRANSLATION_SERVICE)${NC}" echo "" echo -e " ${BOLD}Providers:${NC}" show_status "Google " "GOOGLE_TRANSLATE_ENABLED" show_status "Ollama " "OLLAMA_BASE_URL" "OLLAMA_ENABLED" show_status "DeepSeek " "DEEPSEEK_API_KEY" "DEEPSEEK_ENABLED" show_status "Minimax " "MINIMAX_API_KEY" "MINIMAX_ENABLED" show_status "DeepL " "DEEPL_API_KEY" "DEEPL_ENABLED" show_status "OpenAI " "OPENAI_API_KEY" "OPENAI_ENABLED" show_status "OpenRouter " "OPENROUTER_API_KEY" "OPENROUTER_ENABLED" echo "" echo -e " ${BOLD}Stripe:${NC}" show_status "Secret Key " "STRIPE_SECRET_KEY" show_status "Webhook " "STRIPE_WEBHOOK_SECRET" show_status "Starter " "STRIPE_STARTER_PRICE_ID" show_status "Pro " "STRIPE_PRO_PRICE_ID" show_status "Business " "STRIPE_BUSINESS_PRICE_ID" echo "" echo -e "${BOLD}Actions:${NC}" echo " 1) DeepSeek 4) OpenAI 7) Stripe" echo " 2) Minimax 5) DeepL 8) Mot de passe admin" echo " 3) OpenRouter 6) Ollama 9) Changer provider par defaut" echo "" echo " 0) Quitter v) Voir tout (.env brut)" echo "" echo -ne "${YELLOW}Choix:${NC} " read -r choice case "$choice" in 1) echo -e "\n${BOLD}--- DeepSeek ---${NC}" echo " https://platform.deepseek.com/api_keys" ask_key "API Key" "DEEPSEEK_API_KEY" ask_value "Modele" "DEEPSEEK_MODEL" "deepseek-chat" ask_value "Base URL" "DEEPSEEK_BASE_URL" "https://api.deepseek.com/v1" if [ -n "$(get_env DEEPSEEK_API_KEY)" ]; then set_env "DEEPSEEK_ENABLED" "true" echo -e " ${GREEN}Provider DeepSeek ACTIVE${NC}" else set_env "DEEPSEEK_ENABLED" "false" echo -e " ${RED}Provider DeepSeek DESACTIVE (pas de cle)${NC}" fi restart_hint ;; 2) echo -e "\n${BOLD}--- Minimax (m2.7 / MiniMax-M1) ---${NC}" echo " https://platform.minimaxi.com/" ask_key "API Key" "MINIMAX_API_KEY" ask_value "Modele" "MINIMAX_MODEL" "MiniMax-M1" ask_value "Base URL" "MINIMAX_BASE_URL" "https://api.minimax.chat/v1" ask_value "Group ID (optionnel)" "MINIMAX_GROUP_ID" "" if [ -n "$(get_env MINIMAX_API_KEY)" ]; then set_env "MINIMAX_ENABLED" "true" echo -e " ${GREEN}Provider Minimax ACTIVE${NC}" else set_env "MINIMAX_ENABLED" "false" echo -e " ${RED}Provider Minimax DESACTIVE (pas de cle)${NC}" fi restart_hint ;; 3) echo -e "\n${BOLD}--- OpenRouter ---${NC}" echo " https://openrouter.ai/keys" ask_key "API Key" "OPENROUTER_API_KEY" ask_value "Modele" "OPENROUTER_MODEL" "deepseek/deepseek-chat" if [ -n "$(get_env OPENROUTER_API_KEY)" ]; then set_env "OPENROUTER_ENABLED" "true" echo -e " ${GREEN}Provider OpenRouter ACTIVE${NC}" else set_env "OPENROUTER_ENABLED" "false" echo -e " ${RED}Provider OpenRouter DESACTIVE${NC}" fi restart_hint ;; 4) echo -e "\n${BOLD}--- OpenAI ---${NC}" echo " https://platform.openai.com/api-keys" ask_key "API Key" "OPENAI_API_KEY" ask_value "Modele" "OPENAI_MODEL" "gpt-4o-mini" ask_value "Base URL" "OPENAI_BASE_URL" "https://api.openai.com/v1" if [ -n "$(get_env OPENAI_API_KEY)" ]; then set_env "OPENAI_ENABLED" "true" echo -e " ${GREEN}Provider OpenAI ACTIVE${NC}" else set_env "OPENAI_ENABLED" "false" echo -e " ${RED}Provider OpenAI DESACTIVE${NC}" fi restart_hint ;; 5) echo -e "\n${BOLD}--- DeepL ---${NC}" echo " https://www.deepl.com/pro-api" ask_key "API Key" "DEEPL_API_KEY" if [ -n "$(get_env DEEPL_API_KEY)" ]; then set_env "DEEPL_ENABLED" "true" echo -e " ${GREEN}Provider DeepL ACTIVE${NC}" else set_env "DEEPL_ENABLED" "false" echo -e " ${RED}Provider DeepL DESACTIVE${NC}" fi restart_hint ;; 6) echo -e "\n${BOLD}--- Ollama (local) ---${NC}" ask_value "URL" "OLLAMA_BASE_URL" "http://ollama:11434" ask_value "Modele" "OLLAMA_MODEL" "llama3" set_env "OLLAMA_ENABLED" "true" echo -e " ${GREEN}Provider Ollama ACTIVE${NC}" restart_hint ;; 7) echo -e "\n${BOLD}--- Stripe ---${NC}" echo " Dashboard: https://dashboard.stripe.com" echo " API Keys: https://dashboard.stripe.com/apikeys" echo " Webhooks: https://dashboard.stripe.com/webhooks" echo " Products: https://dashboard.stripe.com/products" echo "" echo -e " ${CYAN}Mode test: utilise sk_test_... pour tester${NC}" echo -e " ${CYAN}Carte test: 4242 4242 4242 4242${NC}" echo "" ask_key "Secret Key (sk_...)" "STRIPE_SECRET_KEY" ask_key "Webhook Secret (whsec_...)" "STRIPE_WEBHOOK_SECRET" ask_key "Price ID Starter (price_...)" "STRIPE_STARTER_PRICE_ID" ask_key "Price ID Pro (price_...)" "STRIPE_PRO_PRICE_ID" ask_key "Price ID Business (price_...)" "STRIPE_BUSINESS_PRICE_ID" echo "" echo -e " ${GREEN}Stripe configure${NC}" restart_hint ;; 8) echo -e "\n${BOLD}--- Mot de passe admin ---${NC}" echo -ne " Nouveau mot de passe: " stty -echo 2>/dev/null || true read -r new_pass stty echo 2>/dev/null || true echo "" echo -ne " Confirmer: " stty -echo 2>/dev/null || true read -r new_pass2 stty echo 2>/dev/null || true echo "" if [ "$new_pass" != "$new_pass2" ]; then echo -e " ${RED}Ne correspondent pas${NC}" elif [ -z "$new_pass" ]; then echo -e " ${RED}Vide${NC}" else echo -e " ${CYAN}Generation bcrypt...${NC}" NEW_HASH=$(docker run --rm python:3.12-slim bash -c \ "pip install 'passlib[bcrypt]' bcrypt > /dev/null 2>&1 && \ python3 -c \"from passlib.context import CryptContext; \ print(CryptContext(schemes=['bcrypt']).hash('${new_pass}'))\"" 2>/dev/null) if [ -n "$NEW_HASH" ]; then set_env "ADMIN_PASSWORD_HASH" "$NEW_HASH" echo -e " ${GREEN}Mot de passe mis a jour${NC}" restart_hint else echo -e " ${RED}Erreur generation hash${NC}" fi fi ;; 9) echo -e "\n${BOLD}--- Provider par defaut ---${NC}" echo " Actuel: $(get_env TRANSLATION_SERVICE)" echo "" echo " 1) google 5) deepseek" echo " 2) ollama 6) minimax" echo " 3) deepl 7) openrouter" echo " 4) openai" echo "" echo -ne " Choix: " read -r svc case "$svc" in 1) set_env "TRANSLATION_SERVICE" "google" ;; 2) set_env "TRANSLATION_SERVICE" "ollama" ;; 3) set_env "TRANSLATION_SERVICE" "deepl" ;; 4) set_env "TRANSLATION_SERVICE" "openai" ;; 5) set_env "TRANSLATION_SERVICE" "deepseek" ;; 6) set_env "TRANSLATION_SERVICE" "minimax" ;; 7) set_env "TRANSLATION_SERVICE" "openrouter" ;; *) echo -e " ${RED}Invalide${NC}" ;; esac echo -e " ${GREEN}Provider par defaut: $(get_env TRANSLATION_SERVICE)${NC}" restart_hint ;; v) echo "" echo -e "${RED}${BOLD}ATTENTION: Secrets visibles!${NC}" echo -ne "${YELLOW}Taper 'oui':${NC} " read -r confirm if [ "$confirm" = "oui" ]; then echo "" grep -v "^#" "$ENV_FILE" | grep -v "^$" fi ;; 0) echo -e "\n${GREEN}Au revoir!${NC}" exit 0 ;; *) echo -e "${RED}Choix invalide${NC}" ;; esac done