./discourse-setup يضع اسم مستخدم SMTP في بداية كلمة مرور SMTP

توصيات تم إنشاؤها بواسطة LLM/AI

\nفيما يلي تصحيح دقيق يقوم بما يلي:\n\n- يتوقف عن استخدام sed\n- ينشئ عنوان URL مشفر بنسبة SMTP_URL\n- يقوم بتحرير containers/app.yml باستخدام Ruby’s YAML (Psych)، لذا يتم التعامل مع الاقتباس/الهروب من YAML بواسطة محلل حقيقي\n- يحذف متغيرات SMTP لكل مفتاح لتجنب التناقضات\n\nقم بالتطبيق باستخدام git apply -p0 في مستودع discourse_docker.\n\n- - -\n\nالتصحيح 1 -\n\ndiscourse-setup\n\n(كتابة SMTP باستخدام Ruby YAML، وليس 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+ # بناء عنوان URL مشفر بنسبة SMTP_URL باستخدام مكتبة Python القياسية (لا توجد ألعاب هروب من 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+ # هام: قراءة المتغيرات بدون تحريف الشرطة المائلة العكسية\n+ # (تأتي هذه من مطالبات سابقة؛ فقط تأكد من استخدام -r في وقت المطالبة)\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+ # استخدام Ruby لتحميل/تعديل/إخراج YAML بأمان (يقضي على 3 طبقات من الهروب)\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+# التأكد من أن الهيكل العلوي هو Hash ويحتوي على env\n+unless doc.is_a?(Hash)\n+ abort \"containers/app.yml does not parse to a Hash\"\n+end\n+doc[\"env\"] ||= {}\n+env = doc[\"env\"]\n+\n+# كتابة SMTP_URL في سطر واحد؛ حذف المتغيرات لكل مفتاح لتجنب التعارضات\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+# إخراج مرة أخرى. (Psych يحافظ على السلاسل النصية المقتبسة بأمان حسب الحاجة.)\n+File.write(path, Psych.dump(doc))\n+RUBY\n+\n+ # فحص سريع للتأكد من فشل \"كلمة المرور مسبوقة باسم المستخدم\" الكلاسيكي\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 missing after write\"\n+creds = m.group(1).split('@',1)[0].split('://',1)[-1]\n+assert \":\" in creds, \"SMTP_URL creds missing ':'\"\n+u, p = creds.split(':',1)\n+assert not p.startswith(u), \"Password appears prefixed by username\"\n+print(\"SMTP_URL looks sane.\")\n+PY\n+}\n+\n- # كتابة إدخالات SMTP لكل مفتاح (العنوان/المنفذ/اسم المستخدم/كلمة المرور)\n- # (قديم: تم تنفيذه عبر استبدالات sed)\n- # ملاحظة: تاريخياً هش مع الأحرف الخاصة\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+ # (تمت إزالة كتابات المفاتيح القديمة لصالح SMTP_URL عبر YAML)\n+}\n\n\nثم التصحيح 2 -\n\ntemplates/web.template.yml\n\n(لتوثيق المسار الأكثر أمانًا)\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+ ## التكوين المفضل لـ SMTP في سطر واحد (تم تعيينه بواسطة discourse-setup):\n+ ## تشفير اسم المستخدم وكلمة المرور بنسبة مئوية؛ مثال:\n+ ## SMTP_URL: \"smtp://user%40example.com:p%40ss%3Aword@smtp.example.com:587\"\n+ ##\n+ #SMTP_URL:\n+\n ## إذا لم تتمكن من استخدام SMTP_URL، يمكنك تعيين متغيرات لكل مفتاح بدلاً من ذلك.\n ## احذر من أن تعديل تلك الأسطر بأدوات shell يمكن أن يكون هشًا إذا كانت القيم تتضمن\n ## أحرفًا مثل @، :، /، \"، \\، أو أسطر جديدة.\n\n\nلماذا يعمل هذا (وما الذي يتجنبه)\n\t•\tطبقة bash: نقوم فقط بتضمين متغيرات بسيطة؛ يتم تمرير الأسرار إلى Python/Ruby عبر stdin/argv، وليس من خلال تعبيرات sed العادية أو تقييمات shell.\n\t•\tطبقة sed: تمت إزالتها بالكامل.\n\t•\tطبقة YAML: يتعامل Ruby/Psych مع الاقتباس والهروب بشكل صحيح؛ لا يوجد اقتباس يدوي.\n\t•\tبيانات اعتماد SMTP: تشفير النسبة المئوية في SMTP_URL هو المكان المناسب لتشفير الأحرف الخاصة للمصادقة.\n\nإذا كنت تفضل الاحتفاظ بالمتغيرات لكل مفتاح، يمكنني أن أقدم لك تصحيحًا شقيقًا يستخدم نفس نهج Ruby-YAML لتعيين DISCOURSE_SMTP_* مباشرة (لا يزال بدون sed)، ولكن مسار SMTP_URL هو الأكثر نظافة لأنه مفتاح واحد، كتابة واحدة، خطوة تشفير واحدة.\n