corentin_wakdo/.env.example
Imugiii 693e4a03bf
All checks were successful
CI / secret-scan (pull_request) Successful in 15s
CI / php-lint (pull_request) Successful in 28s
CI / static-tests (pull_request) Successful in 1m6s
CI / js-tests (pull_request) Successful in 40s
CI / secret-scan (push) Successful in 14s
CI / php-lint (push) Successful in 33s
CI / static-tests (push) Successful in 1m11s
CI / js-tests (push) Successful in 38s
feat(auth): envoi reel de l'email de reset via relais SMTP (Brevo)
Client SMTP maison (zero lib, contrainte from-scratch) : ESMTP + STARTTLS +
AUTH LOGIN, conduit par SmtpClient contre un SmtpTransport injectable (seam de
test). SmtpMailer assemble un message text/plain UTF-8 (dot-stuffing, en-tetes
RFC2047) et implemente l'interface Mailer existante. PasswordResetController
choisit SmtpMailer si SMTP_HOST+USER+PASSWORD presents, sinon garde LogMailer
(dev sans infra mail inchange).

STARTTLS exige avant AUTH (pas d'auth en clair). Garde anti-injection CRLF sur
les adresses (SmtpClient) + filter_var du destinataire (SmtpMailer). readReply
borne (anti-boucle sur reponse malformee). Secrets uniquement en .env (hote) :
placeholders dans .env.example / .env.prod.example, rien de versionne.

Revue compliance : verdict block initial (injection CRLF + readReply non borne),
2 must_fix corriges + tests de regression. 8 tests SMTP, 429 total, PHPStan L6.
2026-06-23 13:31:47 +00:00

146 lines
6.2 KiB
Text

#
# Wakdo - template de configuration
#
# Usage :
# cp .env.example .env
# docker compose up -d
#
# Ce template fonctionne EN LOCAL tel quel (valeurs dev) : la stack est joignable
# sur http://kiosk.localhost:8080 (borne) et http://admin.localhost:8080 (admin).
# Le deploiement derriere un reverse proxy (Traefik) se fait via l'overlay
# docker-compose.prod.yml + les variables du bloc "Deploiement prod" en fin de
# fichier. En prod : changer les mots de passe, APP_DEBUG=false, vrais FQDN.
#
# ===================================================================
# Environnement applicatif
# ===================================================================
APP_ENV=dev # dev | staging | prod
APP_DEBUG=true # true en dev, false en prod
APP_TIMEZONE=Europe/Paris
# Port hote publie par wakdo-web (acces local). Change si 8080 est pris.
HTTP_PORT=8080
# Hostnames des deux vhosts Apache (ServerName). En local : *.localhost resout
# vers 127.0.0.1 nativement. En prod : les vrais FQDN (voir bloc prod en bas).
APP_HOST_KIOSK=kiosk.localhost
APP_HOST_ADMIN=admin.localhost
# URLs publiques (consommees par l'app). En local = les hostnames sur HTTP_PORT.
APP_URL_KIOSK=http://kiosk.localhost:8080
APP_URL_ADMIN=http://admin.localhost:8080
# ===================================================================
# Base de donnees (MariaDB)
# ===================================================================
# Valeurs dev ci-dessous : OK en local. EN PROD : mots de passe forts.
# wakdo-db est sur le reseau interne, aucun port expose a l'hote.
DB_HOST=wakdo-db # nom du service docker-compose
DB_PORT=3306
DB_NAME=wakdo
DB_USER=wakdo
DB_PASSWORD=wakdo_dev_password
DB_ROOT_PASSWORD=wakdo_dev_root_password
# ===================================================================
# Sessions
# ===================================================================
SESSION_LIFETIME_IDLE=14400 # 4h en secondes - idle timeout
SESSION_LIFETIME_ABSOLUTE=36000 # 10h en secondes - absolute timeout
SESSION_NAME=WAKDO_SID # nom du cookie (evite PHPSESSID)
# ===================================================================
# Securite
# ===================================================================
# Origine autorisee pour les requetes CORS de l'API. Doit correspondre
# exactement a APP_URL_KIOSK (pas de wildcard).
CORS_ALLOWED_ORIGIN=http://kiosk.localhost:8080
# Algorithme de hashage : argon2id, FIXE dans le code (App\Auth\PasswordHasher),
# choix security-by-design non configurable. Seuls les COUTS ci-dessous sont reglables.
# Parametres de cout argon2id (password_hash options). Defauts alignes OWASP
# (memoire >= 19 MiB, >= 2 iterations). Servent aussi au hash du PIN equipier.
ARGON2_MEMORY_COST=65536 # KiB (64 MiB)
ARGON2_TIME_COST=4 # nombre d'iterations
ARGON2_THREADS=1 # parallelisme (1 = portable, deterministe)
# ===================================================================
# Anti brute-force - throttling de connexion (security-by-design)
# ===================================================================
# Deux gardes : par compte (user.failed_login_attempts / lockout_until) et par IP
# (table login_throttle). Backoff degressif, pas de lock definitif.
ACCOUNT_LOCKOUT_THRESHOLD=5
ACCOUNT_LOCKOUT_BASE_SECONDS=60
ACCOUNT_LOCKOUT_MAX_SECONDS=900 # plafond du backoff (15 min)
IP_THROTTLE_WINDOW_SECONDS=900 # 15 min
IP_THROTTLE_MAX_ATTEMPTS=20 # par IP sur la fenetre
# PIN equipier pour actions sensibles. Chiffres, bornes min ET max (RG-T18).
STAFF_PIN_MIN_LENGTH=4
STAFF_PIN_MAX_LENGTH=12
# Throttle du PIN d'action sensible (RG-T22) - compteurs SEPARES du login,
# dimension = utilisateur agissant. Bornes plus permissives que le login.
PIN_THROTTLE_THRESHOLD=5
PIN_THROTTLE_BASE_SECONDS=30
PIN_THROTTLE_MAX_SECONDS=300
PIN_THROTTLE_WINDOW_SECONDS=900
# Expiration du token de reinitialisation de mot de passe (secondes).
PASSWORD_RESET_TTL=3600 # 1h
# ===================================================================
# Retention des donnees (RGPD)
# ===================================================================
# Purges executees par le service cron (docker/cron/crontab).
AUDIT_LOG_RETENTION_DAYS=365 # journal d'audit ~12 mois
THROTTLE_PURGE_AFTER_HOURS=24 # login_throttle : lignes sans lockout actif > 24h
ORDER_RETENTION_DAYS=1095 # commandes (historique/stats) ~3 ans
# ===================================================================
# Upload images produits
# ===================================================================
UPLOAD_MAX_SIZE_MB=5
UPLOAD_ALLOWED_MIME=image/jpeg,image/png,image/webp
# ===================================================================
# Cron (fenetre de maintenance 01h30 - 09h30)
# ===================================================================
CRON_TIMEZONE=Europe/Paris
# ===================================================================
# Deploiement prod (overlay docker-compose.prod.yml) - OPTIONNEL
# ===================================================================
# A ignorer pour un usage local. Necessaire UNIQUEMENT derriere un reverse proxy
# Traefik, avec : docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
#
# En prod, surcharger aussi : APP_ENV=prod, APP_DEBUG=false, mots de passe forts,
# et APP_HOST_*/APP_URL_*/CORS_ALLOWED_ORIGIN avec les vrais FQDN HTTPS.
#
# Nom du reseau Docker externe partage avec le Traefik de l'hote (doit exister
# AVANT le up : cree par la stack Traefik, ou `docker network create <nom>`).
REVERSE_PROXY_NETWORK=admin_proxy
# ===================================================================
# Envoi d'email (reinitialisation mot de passe) - OPTIONNEL
# ===================================================================
# Absentes en local : l'app journalise le lien de reset (LogMailer), aucun envoi.
# Renseigner SMTP_HOST + SMTP_USER + SMTP_PASSWORD active l'envoi via relais SMTP.
# Mettre les vraies valeurs uniquement dans le .env de l'hote (jamais versionnees).
# SMTP_HOST=smtp-relay.brevo.com
# SMTP_PORT=587
# SMTP_USER=
# SMTP_PASSWORD=
# MAIL_FROM_EMAIL=noreply@example.com
# MAIL_FROM_NAME=Wakdo