Recommandations générées par LLM/IA
\nVoici un correctif ciblé qui :\n\n- arrête d’utiliser sed\n- construit une URL SMTP encodée en pourcentage\n- modifie containers/app.yml via le module YAML (Psych) de Ruby, de sorte que l’échappement/le codage YAML est géré par un véritable analyseur\n- supprime les variables SMTP par clé pour éviter les contradictions\n\nAppliquez avec git apply -p0 dans le dépôt discourse_docker.\n\n- - -\n\nCorrectif 1 -\n\ndiscourse-setup\n\n(écrit SMTP en utilisant YAML Ruby, pas sed)\n\ndiff\n--- a/discourse-setup\n+++ b/discourse-setup\n@@ -867,6 +867,77 @@ write_smtp_settings() {\n local app_yml=\"containers/app.yml\"\n [[ -f \"$app_yml\" ]] || die \"Cannot find $app_yml. Did you run bootstrap?\"\n\n+ # Construit une URL SMTP encodée en URL à l'aide de la bibliothèque standard Python (pas de jeux d'échappement shell)\n+ urlencode() {\n+ python3 - \u003c\u003c'PY'\n+import sys, urllib.parse\n+print(urllib.parse.quote(sys.stdin.read().strip(), safe='._~-'))\n+PY\n+ }\n+\n+ # IMPORTANT : lit les variables sans permutation des antislashs\n+ # (celles-ci proviennent de invites précédentes ; assurez-vous simplement que -r est utilisé au moment de l'invite)\n+ local addr=\"$smtp_address\"\n+ local port=\"$smtp_port\"\n+ local user_enc pass_enc\n+ user_enc=\"$(printf '%s' \"$smtp_user\" | urlencode)\"\n+ pass_enc=\"$(printf '%s' \"$smtp_password\" | urlencode)\"\n+ local smtp_url=\"smtp://${user_enc}:${pass_enc}@${addr}:${port}\"\n+\n+ # Utilise Ruby pour charger/modifier/sauvegarder YAML en toute sécurité (supprime 3 couches d'échappement)\n+ ruby - \u003c\u003c'RUBY' \"$app_yml\" \"$smtp_url\"\n+require \"yaml\"\n+require \"psych\"\n+path, url = ARGV\n+doc = YAML.safe_load(File.read(path), permitted_classes: [], aliases: true) || {}\n+\n+# Assure que la structure de niveau supérieur est un Hash et a env\n+unless doc.is_a?(Hash)\n+ abort \"containers/app.yml ne se parse pas en Hash\"\n+end\n+doc[\"env\"] ||= {}\n+env = doc[\"env\"]\n+\n+# Écrit SMTP_URL sur une seule ligne ; supprime les variables par clé pour éviter les conflits\n+env[\"SMTP_URL\"] = url\n+%w[DISCOURSE_SMTP_ADDRESS DISCOURSE_SMTP_PORT DISCOURSE_SMTP_USER_NAME DISCOURSE_SMTP_PASSWORD].each { |k| env.delete(k) }\n+\n+# Sauvegarde. (Psych préserve les chaînes correctement échappées si nécessaire.)\n+File.write(path, Psych.dump(doc))\n+RUBY\n+\n+ # vérification rapide pour l'échec classique « mot de passe préfixé par le nom d'utilisateur »\n+ python3 - \u003c\u003c'PY'\n+import re, sys\n+y = open(\"containers/app.yml\",\"r\",encoding=\"utf-8\").read()\n+m = re.search(r'^\\s*SMTP_URL:\\s*(?:\"|\\')?([^\\r\\n\"\\']+)', y, re.M)\n+assert m, \"SMTP_URL manquant après écriture\"\n+creds = m.group(1).split('@',1)[0].split('://',1)[-1]\n+assert \":\" in creds, \"Identifiants SMTP_URL manquants ':'\"\n+u, p = creds.split(':',1)\n+assert not p.startswith(u), \"Le mot de passe semble préfixé par le nom d'utilisateur\"\n+print(\"SMTP_URL semble correct.\")\n+PY\n+}\n+\n- # Écrit les entrées SMTP par clé (adresse/port/nom d'utilisateur/mot de passe)\n- # (hérité : effectué via des substitutions sed)\n- # NOTE : historiquement fragile avec les caractères spéciaux\n- update_setting_yaml \"DISCOURSE_SMTP_ADDRESS\" \"$smtp_address\"\n- update_setting_yaml \"DISCOURSE_SMTP_PORT\" \"$smtp_port\"\n- update_setting_yaml \"DISCOURSE_SMTP_USER_NAME\" \"$smtp_user\"\n- update_setting_yaml \"DISCOURSE_SMTP_PASSWORD\" \"$smtp_password\"\n-}\n+ # (écritures héritées par clé supprimées au profit de SMTP_URL via YAML)\n+}\n\n\npuis Correctif 2 -\n\ntemplates/web.template.yml\n\n(pour documenter le chemin plus sûr)\n\ndiff\n--- a/templates/web.template.yml\n+++ b/templates/web.template.yml\n@@ -68,6 +68,14 @@ params:\n DISCOURSE_SMTP_ENABLE_START_TLS: true\n #DISCOURSE_NOTIFICATION_EMAIL: noreply@example.com\n\n+ ## Configuration SMTP préférée sur une seule ligne (définie par discourse-setup) :\n+ ## Encodez le nom d'utilisateur et le mot de passe en URL ; exemple :\n+ ## SMTP_URL: \"smtp://user%40example.com:p%40ss%3Aword@smtp.example.com:587\"\n+ ##\n+ #SMTP_URL:\n+\n ## Si vous ne pouvez pas utiliser SMTP_URL, vous pouvez définir des variables par clé à la place.\n ## Attention, la modification de ces lignes avec des outils shell peut être fragile si les valeurs incluent\n ## des caractères tels que @, :, /, \", \\ ou des sauts de ligne.\n\n\nPourquoi cela fonctionne (et ce que cela évite)\n\t•\tcouche bash : nous n’intercalons que des variables simples ; les secrets sont passés à Python/Ruby via stdin/argv, pas via des expressions régulières sed ou des évaluations shell.\n\t•\tcouche sed : entièrement supprimée.\n\t•\tcouche YAML : Ruby/Psych gère correctement le codage et l’échappement ; pas de codage manuel.\n\t•\tidentifiants SMTP : l’encodage % dans SMTP_URL est le bon endroit pour encoder les caractères spéciaux pour l’authentification.\n\nSi vous préférez conserver les variables par clé, je peux vous fournir un correctif sœur qui utilise la même approche Ruby-YAML pour définir directement DISCOURSE_SMTP_* (toujours sans sed), mais la voie SMTP_URL est la plus propre car c’est une clé, une écriture, une étape d’encodage.\n