feat: add API key management script
Interactive menu to add/update/clear API keys: - Translation: OpenAI, DeepL, OpenRouter - Payment: Stripe (secret, webhook, price IDs) - Admin password change with bcrypt - Switch translation provider - Status overview with masked keys Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
231
scripts/manage-keys.sh
Normal file
231
scripts/manage-keys.sh
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ============================================
|
||||||
|
# Wordly.art - Gestion des cles API
|
||||||
|
# ============================================
|
||||||
|
# Ajouter, modifier ou supprimer des cles API
|
||||||
|
# Usage: bash scripts/manage-keys.sh
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
ENV_FILE=".env"
|
||||||
|
|
||||||
|
# Couleurs
|
||||||
|
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}Fichier .env non trouve. Lance d'abord: bash scripts/setup-env.sh${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fonction pour lire une valeur dans .env
|
||||||
|
get_env() {
|
||||||
|
grep "^${1}=" "$ENV_FILE" 2>/dev/null | cut -d'=' -f2- || echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour ecrire une valeur dans .env
|
||||||
|
set_env() {
|
||||||
|
local key="$1"
|
||||||
|
local value="$2"
|
||||||
|
if grep -q "^${key}=" "$ENV_FILE"; then
|
||||||
|
sed -i "s|^${key}=.*|${key}=${value}|" "$ENV_FILE"
|
||||||
|
else
|
||||||
|
echo "${key}=${value}" >> "$ENV_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour effacer une valeur dans .env
|
||||||
|
clear_env() {
|
||||||
|
local key="$1"
|
||||||
|
sed -i "s|^${key}=.*|${key}=|" "$ENV_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour afficher le statut d'une cle
|
||||||
|
show_key_status() {
|
||||||
|
local name="$1"
|
||||||
|
local key="$2"
|
||||||
|
local value=$(get_env "$key")
|
||||||
|
if [ -n "$value" ] && [ "$value" != "" ]; then
|
||||||
|
local masked="${value:0:8}...${value: -4}"
|
||||||
|
echo -e " ${GREEN}OK${NC} ${name}: ${masked}"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}--${NC} ${name}: ${YELLOW}non configure${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fonction pour demander une cle
|
||||||
|
ask_key() {
|
||||||
|
local name="$1"
|
||||||
|
local 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 cle (Enter pour garder, 'x' pour 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}Cle supprimee${NC}"
|
||||||
|
elif [ -n "$value" ]; then
|
||||||
|
set_env "$key" "$value"
|
||||||
|
echo -e " ${GREEN}Cle mise a jour${NC}"
|
||||||
|
else
|
||||||
|
echo -e " ${CYAN}Inchange${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===========================================
|
||||||
|
# Menu principal
|
||||||
|
# ===========================================
|
||||||
|
while true; do
|
||||||
|
echo ""
|
||||||
|
echo -e "${CYAN}${BOLD}=========================================${NC}"
|
||||||
|
echo -e "${CYAN}${BOLD} Wordly.art - Gestion des cles API${NC}"
|
||||||
|
echo -e "${CYAN}${BOLD}=========================================${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e "${BOLD}Statut actuel :${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Traduction
|
||||||
|
echo -e " ${BOLD}Traduction :${NC}"
|
||||||
|
show_key_status "OpenAI" "OPENAI_API_KEY"
|
||||||
|
show_key_status "DeepL" "DEEPL_API_KEY"
|
||||||
|
show_key_status "OpenRouter" "OPENROUTER_API_KEY"
|
||||||
|
show_key_status "Google" "GOOGLE_API_KEY"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Paiement
|
||||||
|
echo -e " ${BOLD}Paiement :${NC}"
|
||||||
|
show_key_status "Stripe Secret" "STRIPE_SECRET_KEY"
|
||||||
|
show_key_status "Stripe Webhook" "STRIPE_WEBHOOK_SECRET"
|
||||||
|
show_key_status "Stripe Price Starter" "STRIPE_STARTER_PRICE_ID"
|
||||||
|
show_key_status "Stripe Price Pro" "STRIPE_PRO_PRICE_ID"
|
||||||
|
show_key_status "Stripe Price Business" "STRIPE_BUSINESS_PRICE_ID"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Menu
|
||||||
|
echo -e "${BOLD}Actions :${NC}"
|
||||||
|
echo " 1) Configurer OpenAI"
|
||||||
|
echo " 2) Configurer DeepL"
|
||||||
|
echo " 3) Configurer OpenRouter"
|
||||||
|
echo " 4) Configurer Stripe (toutes les cles)"
|
||||||
|
echo " 5) Changer le mot de passe admin"
|
||||||
|
echo " 6) Changer le service de traduction"
|
||||||
|
echo " 7) Tout afficher (attention: secrets visibles)"
|
||||||
|
echo " 0) Quitter"
|
||||||
|
echo ""
|
||||||
|
echo -ne "${YELLOW}Choix:${NC} "
|
||||||
|
read -r choice
|
||||||
|
|
||||||
|
case "$choice" in
|
||||||
|
1)
|
||||||
|
echo -e "\n${BOLD}--- OpenAI ---${NC}"
|
||||||
|
echo " Ou: https://platform.openai.com/api-keys"
|
||||||
|
ask_key "OpenAI" "OPENAI_API_KEY"
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
echo -e "\n${BOLD}--- DeepL ---${NC}"
|
||||||
|
echo " Ou: https://www.deepl.com/pro-api (gratuit 500k caracteres/mois)"
|
||||||
|
ask_key "DeepL" "DEEPL_API_KEY"
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
echo -e "\n${BOLD}--- OpenRouter ---${NC}"
|
||||||
|
echo " Ou: https://openrouter.ai/keys"
|
||||||
|
ask_key "OpenRouter" "OPENROUTER_API_KEY"
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
echo -e "\n${BOLD}--- Stripe ---${NC}"
|
||||||
|
echo " Ou: https://dashboard.stripe.com/apikeys"
|
||||||
|
echo " Webhooks: https://dashboard.stripe.com/webhooks"
|
||||||
|
echo " Prices: https://dashboard.stripe.com/products"
|
||||||
|
ask_key "Stripe Secret Key" "STRIPE_SECRET_KEY"
|
||||||
|
ask_key "Stripe Webhook Secret" "STRIPE_WEBHOOK_SECRET"
|
||||||
|
ask_key "Price ID Starter" "STRIPE_STARTER_PRICE_ID"
|
||||||
|
ask_key "Price ID Pro" "STRIPE_PRO_PRICE_ID"
|
||||||
|
ask_key "Price ID Business" "STRIPE_BUSINESS_PRICE_ID"
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Cles Stripe configurees.${NC}"
|
||||||
|
echo -e "${YELLOW}Pense a redemarrer: docker compose restart backend${NC}"
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
echo -e "\n${BOLD}--- Changer le 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}Les mots de passe ne correspondent pas${NC}"
|
||||||
|
elif [ -z "$new_pass" ]; then
|
||||||
|
echo -e " ${RED}Mot de passe vide${NC}"
|
||||||
|
else
|
||||||
|
echo -e " ${CYAN}Generation du hash...${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}"
|
||||||
|
echo -e " ${YELLOW}Redemarre le backend: docker compose restart backend${NC}"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}Erreur lors de la generation du hash${NC}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
6)
|
||||||
|
echo -e "\n${BOLD}--- Service de traduction ---${NC}"
|
||||||
|
echo " Actuel: $(get_env TRANSLATION_SERVICE)"
|
||||||
|
echo " 1) ollama (local, gratuit)"
|
||||||
|
echo " 2) deepl (haute qualite)"
|
||||||
|
echo " 3) openai (GPT)"
|
||||||
|
echo " 4) openrouter (multi-modeles)"
|
||||||
|
echo ""
|
||||||
|
echo -ne " Choix: "
|
||||||
|
read -r svc
|
||||||
|
case "$svc" in
|
||||||
|
1) set_env "TRANSLATION_SERVICE" "ollama" ;;
|
||||||
|
2) set_env "TRANSLATION_SERVICE" "deepl" ;;
|
||||||
|
3) set_env "TRANSLATION_SERVICE" "openai" ;;
|
||||||
|
4) set_env "TRANSLATION_SERVICE" "openrouter" ;;
|
||||||
|
*) echo -e " ${RED}Choix invalide${NC}" ;;
|
||||||
|
esac
|
||||||
|
echo -e " ${GREEN}Service mis a jour${NC}"
|
||||||
|
echo -e " ${YELLOW}Redemarre: docker compose restart backend${NC}"
|
||||||
|
;;
|
||||||
|
7)
|
||||||
|
echo ""
|
||||||
|
echo -e "${RED}${BOLD}ATTENTION: Secrets visibles!${NC}"
|
||||||
|
echo -ne "${YELLOW}Taper 'oui' pour continuer:${NC} "
|
||||||
|
read -r confirm
|
||||||
|
if [ "$confirm" = "oui" ]; then
|
||||||
|
echo ""
|
||||||
|
cat "$ENV_FILE" | grep -v "^#" | grep -v "^$"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
0)
|
||||||
|
echo ""
|
||||||
|
echo -e "${GREEN}Au revoir!${NC}"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo -e "${RED}Choix invalide${NC}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user