#!/usr/bin/env bash # ============================================================================= # Neutralisation des comptes de demonstration -- OUTIL DE SECOURS ET D'AUDIT # ============================================================================= # # LE CAS NOMINAL N'A PLUS BESOIN DE CE SCRIPT. # # Le traitement est desormais fait par les migrations, donc automatiquement et # sans risque d'oubli : # # 1730000000007-SeedTestUsers ne s'execute plus si # NODE_ENV=production # 1756000000000-NeutralizeSeedAccountsInProduction filet de securite # 1756000000001-BootstrapAdminFromEnv cree VOTRE administrateur # # Ce script reste utile dans trois situations : # # - une base de production migree AVANT l'ajout de la garde NODE_ENV ; # - un deploiement ou NODE_ENV n'etait pas correctement positionne (le journal # du Job de migration affiche alors "Seeded test users successfully") ; # - une verification manuelle : il affiche l'etat des comptes sans rien # changer s'il n'y a rien a changer. # # ssh deploy@ # sudo bash /opt/xpeditis/infra-prod/scripts/harden-seed-data.sh # # RAPPEL DU PROBLEME # # La migration 1730000000007-SeedTestUsers cree trois comptes dont le mot de # passe est ecrit en clair dans le depot : # # admin@xpeditis.com role ADMIN Password123! # manager@xpeditis.com role MANAGER Password123! # user@xpeditis.com role USER Password123! # # Sur une base de production, cela donne un acces complet a la plateforme a # quiconque a lu le depot. # # Ce script ne SUPPRIME pas les lignes (des cles etrangeres peuvent y pointer, # et une suppression en cascade dans audit_logs serait pire). Il : # 1. renomme les adresses vers un domaine invalide -- ce qui libere au passage # admin@xpeditis.com pour votre vrai compte ; # 2. remplace le mot de passe par une valeur aleatoire inutilisable ; # 3. desactive les comptes (is_active = false). # # Idempotent : peut etre relance sans risque. set -euo pipefail COMPOSE_DIR="${COMPOSE_DIR:-/opt/xpeditis/data-node}" ENV_FILE="${ENV_FILE:-${COMPOSE_DIR}/.env.data}" [[ -f "$ENV_FILE" ]] || { echo "Fichier d'environnement introuvable : $ENV_FILE" >&2; exit 1; } # shellcheck disable=SC1090 set -a; source "$ENV_FILE"; set +a psql_run() { docker compose -f "${COMPOSE_DIR}/docker-compose.data.yml" --env-file "$ENV_FILE" \ exec -T -u postgres postgres psql -v ON_ERROR_STOP=1 -d "$POSTGRES_DB" "$@" } echo ">>> Etat avant intervention" psql_run -c " SELECT email, role, is_active FROM users WHERE email IN ('admin@xpeditis.com','manager@xpeditis.com','user@xpeditis.com'); " echo echo ">>> Neutralisation" psql_run <<'SQL' BEGIN; -- Mot de passe remplace par une valeur aleatoire : le format reste un hash -- Argon2 valide en apparence, mais aucun mot de passe ne peut y correspondre. UPDATE users SET email = 'seed-desactive-' || substr(id::text, 1, 8) || '@invalid.local', -- md5(random()) plutot que gen_random_bytes : pas besoin de l'extension -- pgcrypto, qui n'est pas installee sur cette base. password_hash = '$argon2id$v=19$m=65536,t=3,p=4$' || md5(random()::text) || '$' || md5(random()::text) || md5(clock_timestamp()::text), is_active = false, updated_at = NOW() WHERE email IN ('admin@xpeditis.com', 'manager@xpeditis.com', 'user@xpeditis.com'); COMMIT; SQL echo echo ">>> Etat apres intervention" psql_run -c " SELECT email, role, is_active FROM users WHERE email LIKE 'seed-desactive-%@invalid.local'; " echo echo ">>> Controle : aucun compte de demonstration ne doit subsister" RESTE=$(psql_run -tAc " SELECT count(*) FROM users WHERE email IN ('admin@xpeditis.com','manager@xpeditis.com','user@xpeditis.com'); ") if [[ "$RESTE" != "0" ]]; then echo "ECHEC : ${RESTE} compte(s) de demonstration encore actifs." >&2 exit 1 fi echo "OK : aucun compte de demonstration actif." echo echo ">>> Organisations de demonstration presentes (a examiner, non modifiees)" # Non supprimees automatiquement : les comptes desactives y sont rattaches, et # une suppression en cascade toucherait aussi audit_logs. psql_run -c " SELECT id, name, created_at FROM organizations WHERE name IN ('Test Freight Forwarder Inc.','Demo Shipping Company','Sample Shipper Ltd.'); " cat <<'NEXT' ----------------------------------------------------------------------------- Etape suivante : disposer d'un administrateur. La migration 1756000000001-BootstrapAdminFromEnv s'en charge normalement, a partir de BOOTSTRAP_ADMIN_EMAIL (ConfigMap). Si elle a ete ignoree parce qu'un ADMIN actif existait alors -- typiquement le compte de demonstration que ce script vient de neutraliser -- relancez simplement le Job de migration : kubectl -n xpeditis-prod delete job -l app.kubernetes.io/name=xpeditis-migrate # puis redeployez, ou rejouez le Job pour le tag courant Elle ne rejouera pas les migrations deja appliquees ; pour forcer uniquement l'amorcage, creez votre compte a la main : 1. Inscrivez-vous sur https://app.xpeditis.com/fr/register 2. Promouvez le compte : UPDATE users SET role = 'ADMIN' WHERE email = ''; Dans les deux cas, verifiez qu'il n'existe qu'un seul ADMIN actif : SELECT email, role, is_active FROM users WHERE role = 'ADMIN'; Puis controlez depuis l'exterieur que l'ancien compte est bien mort : curl -s -o /dev/null -w '%{http_code}\n' -X POST \ https://api.xpeditis.com/api/v1/auth/login \ -H 'Content-Type: application/json' \ -d '{"email":"admin@xpeditis.com","password":"Password123!"}' # Attendu : 401 (et surtout pas 200 ni 201) ----------------------------------------------------------------------------- NEXT