Explorar o código

feat: add support for IP address in AutoCert options #1208

0xJacky hai 1 semana
pai
achega
e47fc25480

+ 1 - 0
app/src/api/auto_cert.ts

@@ -22,6 +22,7 @@ export interface DNSProvider {
 export interface AutoCertOptions {
   name?: string
   domains: string[]
+  ip_address?: string
   code?: string
   dns_credential_id?: number | null
   challenge_method: keyof typeof AutoCertChallengeMethod

+ 160 - 2
app/src/components/AutoCertForm/AutoCertForm.vue

@@ -9,6 +9,11 @@ const props = defineProps<{
   hideNote?: boolean
   forceDnsChallenge?: boolean
   keyTypeReadOnly?: boolean
+  isDefaultServer?: boolean
+  hasWildcardServerName?: boolean
+  hasExplicitIpAddress?: boolean
+  isIpCertificate?: boolean
+  needsManualIpInput?: boolean
 }>()
 
 const data = defineModel<AutoCertOptions>('options', {
@@ -16,24 +21,130 @@ const data = defineModel<AutoCertOptions>('options', {
   required: true,
 })
 
+// Local IP address buffer for manual input
+const manualIpAddress = ref('')
+
+// Function to apply manual IP to domains when needed
+function applyManualIpToDomains() {
+  if (props.needsManualIpInput && manualIpAddress.value?.trim()) {
+    if (!data.value.domains)
+      data.value.domains = []
+
+    const trimmedIp = manualIpAddress.value.trim()
+    if (!data.value.domains.includes(trimmedIp)) {
+      data.value.domains.push(trimmedIp)
+    }
+  }
+}
+
 onMounted(() => {
   if (!data.value.key_type)
     data.value.key_type = PrivateKeyTypeEnum.P256
 
   if (props.forceDnsChallenge)
     data.value.challenge_method = AutoCertChallengeMethod.dns01
+  else if (props.isIpCertificate)
+    data.value.challenge_method = AutoCertChallengeMethod.http01
 })
 
 watch(() => props.forceDnsChallenge, v => {
   if (v)
     data.value.challenge_method = AutoCertChallengeMethod.dns01
 })
+
+watch(() => props.isIpCertificate, v => {
+  if (v && !props.forceDnsChallenge)
+    data.value.challenge_method = AutoCertChallengeMethod.http01
+})
+
+// Expose function for parent component to call before submission
+defineExpose({
+  applyManualIpToDomains,
+})
+
+// Check if IPv4 address is private
+function isPrivateIPv4(ip: string): boolean {
+  const parts = ip.split('.').map(part => Number.parseInt(part, 10))
+  const [a, b] = parts
+
+  // 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8 (localhost)
+  return a === 10
+    || (a === 172 && b >= 16 && b <= 31)
+    || (a === 192 && b === 168)
+    || a === 127
+}
+
+// IP address validation function
+function validateIpAddress(_rule: unknown, value: string) {
+  if (!value || value.trim() === '') {
+    return Promise.reject($gettext('Please enter the server IP address'))
+  }
+
+  // Basic IPv4 validation (simplified)
+  const ipv4Regex = /^(?:\d{1,3}\.){3}\d{1,3}$/
+  // Basic IPv6 validation
+  const ipv6Regex = /^(?:[\da-f]{1,4}:){7}[\da-f]{1,4}$|^::1$|^::$/i
+
+  const trimmedValue = value.trim()
+
+  // Additional validation for IPv4 ranges
+  if (ipv4Regex.test(trimmedValue)) {
+    const parts = trimmedValue.split('.')
+    const validRange = parts.every(part => {
+      const num = Number.parseInt(part, 10)
+      return num >= 0 && num <= 255
+    })
+    if (!validRange) {
+      return Promise.reject($gettext('Please enter a valid IPv4 address (0-255 per octet)'))
+    }
+
+    // Warn about private IP addresses
+    if (isPrivateIPv4(trimmedValue)) {
+      return Promise.reject($gettext('Warning: This appears to be a private IP address. '
+        + 'Public CAs like Let\'s Encrypt cannot issue certificates for private IPs. '
+        + 'Use a public IP address or consider using a private CA.'))
+    }
+  }
+  else if (!ipv6Regex.test(trimmedValue)) {
+    return Promise.reject($gettext('Please enter a valid IPv4 or IPv6 address'))
+  }
+
+  return Promise.resolve()
+}
 </script>
 
 <template>
   <div>
+    <!-- IP Certificate Warning -->
+    <AAlert
+      v-if="isIpCertificate && !hideNote"
+      type="warning"
+      show-icon
+      :message="$gettext('IP Certificate Notice')"
+      class="mb-4"
+    >
+      <template #description>
+        <p v-if="isDefaultServer">
+          {{ $gettext('This site is configured as a default server (default_server) for HTTPS (port 443). '
+            + 'IP certificates require Certificate Authority (CA) support and may not be available with all ACME providers.') }}
+        </p>
+        <p v-else-if="hasWildcardServerName">
+          {{ $gettext('This site uses wildcard server name (_) which typically indicates an IP-based certificate. '
+            + 'IP certificates require Certificate Authority (CA) support and may not be available with all ACME providers.') }}
+        </p>
+        <p v-if="needsManualIpInput">
+          {{ $gettext('No specific IP address found in server_name configuration. '
+            + 'Please specify the server IP address below for the certificate.') }}
+        </p>
+        <p>
+          {{ $gettext('For IP-based certificate configurations, only HTTP-01 challenge method is supported. '
+            + 'DNS-01 challenge is not compatible with IP-based certificates.') }}
+        </p>
+      </template>
+    </AAlert>
+
     <AAlert
-      v-if="!hideNote"
+      v-if="!hideNote && !isIpCertificate"
       type="info"
       show-icon
       :message="$gettext('Note')"
@@ -61,6 +172,47 @@ watch(() => props.forceDnsChallenge, v => {
       </template>
     </AAlert>
     <AForm layout="vertical">
+      <!-- IP Address Input for IP certificates without explicit IP -->
+      <AFormItem
+        v-if="needsManualIpInput"
+        :label="$gettext('Server IP Address')"
+        :rules="[{ validator: validateIpAddress, trigger: 'blur' }]"
+      >
+        <AInput
+          v-model:value="manualIpAddress"
+          :placeholder="$gettext('Enter server IP address (e.g., 203.0.113.1 or 2001:db8::1)')"
+        />
+        <template #help>
+          <div class="space-y-2">
+            <p>
+              {{ $gettext('For IP-based certificates, please specify the server IP address that will be included in the certificate.') }}
+            </p>
+            <div class="text-xs text-gray-600">
+              <p class="font-medium">
+                {{ $gettext('Public CA Requirements:') }}
+              </p>
+              <ul class="ml-4 list-disc space-y-1">
+                <li>
+                  {{ $gettext('Must be a public IP address accessible from the internet') }}
+                </li>
+                <li>
+                  {{ $gettext('Port 80 must be open for HTTP-01 challenge validation') }}
+                </li>
+                <li>
+                  {{ $gettext('Private IPs (192.168.x.x, 10.x.x.x, 172.16-31.x.x) will fail') }}
+                </li>
+              </ul>
+              <p class="mt-2 font-medium">
+                {{ $gettext('Private CA:') }}
+              </p>
+              <p class="ml-4">
+                {{ $gettext('Any reachable IP address can be used with private Certificate Authorities') }}
+              </p>
+            </div>
+          </div>
+        </template>
+      </AFormItem>
+
       <AFormItem
         v-if="!forceDnsChallenge"
         :label="$gettext('Challenge Method')"
@@ -69,8 +221,14 @@ watch(() => props.forceDnsChallenge, v => {
           <ASelectOption value="http01">
             {{ $gettext('HTTP01') }}
           </ASelectOption>
-          <ASelectOption value="dns01">
+          <ASelectOption
+            value="dns01"
+            :disabled="isIpCertificate"
+          >
             {{ $gettext('DNS01') }}
+            <span v-if="isIpCertificate" class="text-gray-400 ml-2">
+              ({{ $gettext('Not supported for IP certificates') }})
+            </span>
           </ASelectOption>
         </ASelect>
       </AFormItem>

+ 265 - 174
app/src/language/ar/app.po

@@ -5,10 +5,10 @@ msgid ""
 msgstr ""
 "PO-Revision-Date: 2025-07-14 07:37+0000\n"
 "Last-Translator: mosaati <mohammed.saati@gmail.com>\n"
-"Language-Team: Arabic <https://weblate.nginxui.com/projects/nginx-ui/"
-"frontend/ar/>\n"
+"Language-Team: Arabic "
+"<https://weblate.nginxui.com/projects/nginx-ui/frontend/ar/>\n"
 "Language: ar\n"
-"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
 "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
@@ -33,8 +33,7 @@ msgid "[Nginx UI] Certificate successfully revoked"
 msgstr "[Nginx UI] تم إلغاء الشهادة بنجاح"
 
 #: src/language/generate.ts:37
-msgid ""
-"[Nginx UI] Certificate was used for server, reloading server TLS certificate"
+msgid "[Nginx UI] Certificate was used for server, reloading server TLS certificate"
 msgstr "[Nginx UI] تم استخدام الشهادة للخادم، إعادة تحميل شهادة TLS للخادم"
 
 #: src/language/generate.ts:38
@@ -245,6 +244,10 @@ msgstr ""
 "يجب أن تنتمي جميع النطاقات الفرعية المحددة إلى نفس موفر DNS، وإلا فشل طلب "
 "الشهادة."
 
+#: src/components/AutoCertForm/AutoCertForm.vue:188
+msgid "Any reachable IP address can be used with private Certificate Authorities"
+msgstr "يمكن استخدام أي عنوان IP قابل للوصول مع سلطات الشهادات الخاصة"
+
 #: src/views/preference/tabs/OpenAISettings.vue:32
 msgid "API Base Url"
 msgstr "عنوان URL الأساسي لAPI"
@@ -491,14 +494,13 @@ msgstr "جدول النسخ الاحتياطي"
 
 #: src/components/Notification/notifications.ts:38
 msgid "Backup task %{backup_name} completed successfully, file: %{file_path}"
-msgstr ""
-"تم إنجاز مهمة النسخ الاحتياطي %{backup_name} بنجاح، الملف: %{file_path}"
+msgstr "تم إنجاز مهمة النسخ الاحتياطي %{backup_name} بنجاح، الملف: %{file_path}"
 
 #: src/components/Notification/notifications.ts:34
-msgid ""
-"Backup task %{backup_name} failed during storage upload, error: %{error}"
+msgid "Backup task %{backup_name} failed during storage upload, error: %{error}"
 msgstr ""
-"فشلت مهمة النسخ الاحتياطي %{backup_name} أثناء تحميل التخزين، الخطأ: %{error}"
+"فشلت مهمة النسخ الاحتياطي %{backup_name} أثناء تحميل التخزين، الخطأ: "
+"%{error}"
 
 #: src/components/Notification/notifications.ts:30
 msgid "Backup task %{backup_name} failed to execute, error: %{error}"
@@ -577,8 +579,7 @@ msgstr "الذاكرة المؤقتة"
 
 #: src/views/dashboard/components/ParamsOpt/ProxyCacheConfig.vue:178
 msgid "Cache items not accessed within this time will be removed"
-msgstr ""
-"سيتم إزالة عناصر الذاكرة المؤقتة التي لم يتم الوصول إليها خلال هذا الوقت"
+msgstr "سيتم إزالة عناصر الذاكرة المؤقتة التي لم يتم الوصول إليها خلال هذا الوقت"
 
 #: src/views/dashboard/components/ParamsOpt/ProxyCacheConfig.vue:350
 msgid "Cache loader processing time threshold"
@@ -778,7 +779,7 @@ msgstr "قائمة الشهادات"
 msgid "Challenge error: {0}"
 msgstr "خطأ في التحدي: {0}"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:66
+#: src/components/AutoCertForm/AutoCertForm.vue:197
 msgid "Challenge Method"
 msgstr "طريقة التحدي"
 
@@ -828,23 +829,23 @@ msgstr "تحقق مرة أخرى"
 #: src/language/generate.ts:6
 msgid ""
 "Check if /var/run/docker.sock exists. If you are using Nginx UI Official "
-"Docker Image, please make sure the docker socket is mounted like this: `-v /"
-"var/run/docker.sock:/var/run/docker.sock`. Nginx UI official image uses /var/"
-"run/docker.sock to communicate with the host Docker Engine via Docker Client "
-"API. This feature is used to control Nginx in another container and perform "
-"container replacement rather than binary replacement during OTA upgrades of "
-"Nginx UI to ensure container dependencies are also upgraded. If you don't "
-"need this feature, please add the environment variable "
+"Docker Image, please make sure the docker socket is mounted like this: `-v "
+"/var/run/docker.sock:/var/run/docker.sock`. Nginx UI official image uses "
+"/var/run/docker.sock to communicate with the host Docker Engine via Docker "
+"Client API. This feature is used to control Nginx in another container and "
+"perform container replacement rather than binary replacement during OTA "
+"upgrades of Nginx UI to ensure container dependencies are also upgraded. If "
+"you don't need this feature, please add the environment variable "
 "NGINX_UI_IGNORE_DOCKER_SOCKET=true to the container."
 msgstr ""
 "تحقق مما إذا كان /var/run/docker.sock موجودًا. إذا كنت تستخدم صورة Docker "
-"الرسمية لـ Nginx UI، يرجى التأكد من توصيل مقبس Docker بهذه الطريقة: `-v /var/"
-"run/docker.sock:/var/run/docker.sock`. تستخدم صورة Nginx UI الرسمية /var/run/"
-"docker.sock للتواصل مع محرك Docker المضيف عبر واجهة برمجة تطبيقات Docker "
-"Client. تُستخدم هذه الميزة للتحكم في Nginx في حاوية أخرى وإجراء استبدال "
-"الحاوية بدلاً من استبدال الثنائي أثناء التحديثات OTA لـ Nginx UI لضمان تحديث "
-"تبعيات الحاوية أيضًا. إذا كنت لا تحتاج إلى هذه الميزة، يرجى إضافة متغير "
-"البيئة NGINX_UI_IGNORE_DOCKER_SOCKET=true إلى الحاوية."
+"الرسمية لـ Nginx UI، يرجى التأكد من توصيل مقبس Docker بهذه الطريقة: `-v "
+"/var/run/docker.sock:/var/run/docker.sock`. تستخدم صورة Nginx UI الرسمية "
+"/var/run/docker.sock للتواصل مع محرك Docker المضيف عبر واجهة برمجة تطبيقات "
+"Docker Client. تُستخدم هذه الميزة للتحكم في Nginx في حاوية أخرى وإجراء "
+"استبدال الحاوية بدلاً من استبدال الثنائي أثناء التحديثات OTA لـ Nginx UI "
+"لضمان تحديث تبعيات الحاوية أيضًا. إذا كنت لا تحتاج إلى هذه الميزة، يرجى "
+"إضافة متغير البيئة NGINX_UI_IGNORE_DOCKER_SOCKET=true إلى الحاوية."
 
 #: src/components/SelfCheck/tasks/frontend/https-check.ts:14
 msgid ""
@@ -856,19 +857,19 @@ msgstr ""
 
 #: src/language/generate.ts:8
 msgid ""
-"Check if the nginx access log path exists. By default, this path is obtained "
-"from 'nginx -V'. If it cannot be obtained or the obtained path does not "
-"point to a valid, existing file, an error will be reported. In this case, "
-"you need to modify the configuration file to specify the access log path."
-"Refer to the docs for more details: https://nginxui.com/zh_CN/guide/config-"
-"nginx.html#accesslogpath"
+"Check if the nginx access log path exists. By default, this path is "
+"obtained from 'nginx -V'. If it cannot be obtained or the obtained path "
+"does not point to a valid, existing file, an error will be reported. In "
+"this case, you need to modify the configuration file to specify the access "
+"log path.Refer to the docs for more details: "
+"https://nginxui.com/zh_CN/guide/config-nginx.html#accesslogpath"
 msgstr ""
-"تحقق مما إذا كان مسار سجل الوصول إلى nginx موجودًا. بشكل افتراضي، يتم الحصول "
-"على هذا المسار من 'nginx -V'. إذا لم يتم الحصول عليه أو إذا كان المسار الذي "
-"تم الحصول عليه لا يشير إلى ملف صالح موجود، فسيتم الإبلاغ عن خطأ. في هذه "
-"الحالة، تحتاج إلى تعديل ملف التكوين لتحديد مسار سجل الوصول. راجع الوثائق "
-"لمزيد من التفاصيل: https://nginxui.com/zh_CN/guide/config-nginx."
-"html#accesslogpath"
+"تحقق مما إذا كان مسار سجل الوصول إلى nginx موجودًا. بشكل افتراضي، يتم "
+"الحصول على هذا المسار من 'nginx -V'. إذا لم يتم الحصول عليه أو إذا كان "
+"المسار الذي تم الحصول عليه لا يشير إلى ملف صالح موجود، فسيتم الإبلاغ عن "
+"خطأ. في هذه الحالة، تحتاج إلى تعديل ملف التكوين لتحديد مسار سجل الوصول. "
+"راجع الوثائق لمزيد من التفاصيل: "
+"https://nginxui.com/zh_CN/guide/config-nginx.html#accesslogpath"
 
 #: src/language/generate.ts:9
 msgid "Check if the nginx configuration directory exists"
@@ -884,28 +885,29 @@ msgid ""
 "from 'nginx -V'. If it cannot be obtained or the obtained path does not "
 "point to a valid, existing file, an error will be reported. In this case, "
 "you need to modify the configuration file to specify the error log path. "
-"Refer to the docs for more details: https://nginxui.com/zh_CN/guide/config-"
-"nginx.html#errorlogpath"
+"Refer to the docs for more details: "
+"https://nginxui.com/zh_CN/guide/config-nginx.html#errorlogpath"
 msgstr ""
 "تحقق مما إذا كان مسار سجل أخطاء nginx موجودًا. بشكل افتراضي، يتم الحصول على "
 "هذا المسار من 'nginx -V'. إذا تعذر الحصول عليه أو إذا كان المسار الذي تم "
-"الحصول عليه لا يشير إلى ملف صالح موجود، فسيتم الإبلاغ عن خطأ. في هذه الحالة، "
-"تحتاج إلى تعديل ملف التكوين لتحديد مسار سجل الأخطاء. راجع الوثائق لمزيد من "
-"التفاصيل: https://nginxui.com/zh_CN/guide/config-nginx.html#errorlogpath"
+"الحصول عليه لا يشير إلى ملف صالح موجود، فسيتم الإبلاغ عن خطأ. في هذه "
+"الحالة، تحتاج إلى تعديل ملف التكوين لتحديد مسار سجل الأخطاء. راجع الوثائق "
+"لمزيد من التفاصيل: "
+"https://nginxui.com/zh_CN/guide/config-nginx.html#errorlogpath"
 
 #: src/language/generate.ts:7
 msgid ""
 "Check if the nginx PID path exists. By default, this path is obtained from "
 "'nginx -V'. If it cannot be obtained, an error will be reported. In this "
 "case, you need to modify the configuration file to specify the Nginx PID "
-"path.Refer to the docs for more details: https://nginxui.com/zh_CN/guide/"
-"config-nginx.html#pidpath"
+"path.Refer to the docs for more details: "
+"https://nginxui.com/zh_CN/guide/config-nginx.html#pidpath"
 msgstr ""
-"تحقق مما إذا كان مسار معرف عملية Nginx موجودًا. بشكل افتراضي، يتم الحصول على "
-"هذا المسار من الأمر 'nginx -V'. إذا تعذر الحصول عليه، سيتم الإبلاغ عن خطأ. "
-"في هذه الحالة، تحتاج إلى تعديل ملف التكوين لتحديد مسار معرف عملية Nginx. "
-"راجع الوثائق لمزيد من التفاصيل: https://nginxui.com/zh_CN/guide/config-nginx."
-"html#pidpath"
+"تحقق مما إذا كان مسار معرف عملية Nginx موجودًا. بشكل افتراضي، يتم الحصول "
+"على هذا المسار من الأمر 'nginx -V'. إذا تعذر الحصول عليه، سيتم الإبلاغ عن "
+"خطأ. في هذه الحالة، تحتاج إلى تعديل ملف التكوين لتحديد مسار معرف عملية "
+"Nginx. راجع الوثائق لمزيد من التفاصيل: "
+"https://nginxui.com/zh_CN/guide/config-nginx.html#pidpath"
 
 #: src/language/generate.ts:12
 msgid "Check if the nginx sbin path exists"
@@ -933,8 +935,8 @@ msgstr ""
 
 #: src/language/generate.ts:17
 msgid ""
-"Check if the streams-available and streams-enabled directories are under the "
-"nginx configuration directory"
+"Check if the streams-available and streams-enabled directories are under "
+"the nginx configuration directory"
 msgstr ""
 "تحقق مما إذا كانت الدلائل streams-available و streams-enabled موجودة ضمن "
 "دليل تكوين nginx"
@@ -1551,11 +1553,11 @@ msgstr "بيانات اعتماد DNS"
 msgid "DNS Provider"
 msgstr "مزود DNS"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:73
+#: src/components/AutoCertForm/AutoCertForm.vue:207
 msgid "DNS01"
 msgstr "DNS01"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:103
+#: src/components/AutoCertForm/AutoCertForm.vue:240
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr "لا تقم بتمكين هذا الخيار إلا إذا كنت متأكدًا من أنك بحاجة إليه."
 
@@ -1645,8 +1647,8 @@ msgid ""
 "Due to the security policies of some browsers, you cannot use passkeys on "
 "non-HTTPS websites, except when running on localhost."
 msgstr ""
-"نظرًا لسياسات الأمان لبعض المتصفحات، لا يمكنك استخدام مفاتيح المرور على مواقع "
-"الويب غير HTTPS، إلا عند التشغيل على localhost."
+"نظرًا لسياسات الأمان لبعض المتصفحات، لا يمكنك استخدام مفاتيح المرور على "
+"مواقع الويب غير HTTPS، إلا عند التشغيل على localhost."
 
 #: src/views/site/site_list/SiteDuplicate.vue:72
 #: src/views/site/site_list/SiteList.vue:108
@@ -1849,6 +1851,10 @@ msgstr "النهاية"
 msgid "Enter domain name"
 msgstr "أدخل اسم النطاق"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:162
+msgid "Enter server IP address (e.g., 203.0.113.1 or 2001:db8::1)"
+msgstr "أدخل عنوان IP للخادم (مثال: 203.0.113.1 أو 2001:db8::1)"
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:122
 msgid "Enter your domain"
 msgstr "أدخل نطاقك"
@@ -1926,15 +1932,15 @@ msgstr "تصدير إكسل"
 msgid ""
 "External Account Binding HMAC Key (optional). Should be in Base64 URL "
 "encoding format."
-msgstr ""
-"مفتاح HMAC لربط الحساب الخارجي (اختياري). يجب أن يكون بتنسيق Base64 URL."
+msgstr "مفتاح HMAC لربط الحساب الخارجي (اختياري). يجب أن يكون بتنسيق Base64 URL."
 
 #: src/views/certificate/ACMEUser.vue:90
 msgid ""
-"External Account Binding Key ID (optional). Required for some ACME providers "
-"like ZeroSSL."
+"External Account Binding Key ID (optional). Required for some ACME "
+"providers like ZeroSSL."
 msgstr ""
-"معرف مفتاح الربط الحساب الخارجي (اختياري). مطلوب لبعض موفري ACME مثل ZeroSSL."
+"معرف مفتاح الربط الحساب الخارجي (اختياري). مطلوب لبعض موفري ACME مثل "
+"ZeroSSL."
 
 #: src/views/preference/tabs/NginxSettings.vue:49
 msgid "External Docker Container"
@@ -2383,6 +2389,22 @@ msgstr "للمستخدمين الصينيين"
 msgid "For Chinese user: https://cloud.nginxui.com/"
 msgstr "للمستخدمين الصين: /https://cloud.nginxui.com"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:119
+msgid ""
+"For IP-based certificate configurations, only HTTP-01 challenge method is "
+"supported. DNS-01 challenge is not compatible with IP-based certificates."
+msgstr ""
+"بالنسبة لتكوينات الشهادات القائمة على IP، فإن طريقة التحدي HTTP-01 فقط هي "
+"المدعومة. طريقة التحدي DNS-01 غير متوافقة مع الشهادات القائمة على IP."
+
+#: src/components/AutoCertForm/AutoCertForm.vue:167
+msgid ""
+"For IP-based certificates, please specify the server IP address that will "
+"be included in the certificate."
+msgstr ""
+"بالنسبة للشهادات القائمة على IP، يرجى تحديد عنوان IP الخاص بالخادم الذي "
+"سيتم تضمينه في الشهادة."
+
 #: src/constants/errors/middleware.ts:4
 msgid "Form parse failed"
 msgstr "فشل تحليل النموذج"
@@ -2507,7 +2529,7 @@ msgstr "HTTP"
 msgid "HTTP Challenge Port"
 msgstr "منفذ تحدي HTTP"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:70
+#: src/components/AutoCertForm/AutoCertForm.vue:201
 msgid "HTTP01"
 msgstr "HTTP01"
 
@@ -2527,7 +2549,7 @@ msgstr ""
 "إذا وصل عدد محاولات تسجيل الدخول الفاشلة من عنوان IP إلى الحد الأقصى "
 "للمحاولات في حد دقائق الحظر، سيتم حظر عنوان IP لفترة من الوقت."
 
-#: src/components/AutoCertForm/AutoCertForm.vue:122
+#: src/components/AutoCertForm/AutoCertForm.vue:259
 msgid ""
 "If you want to automatically revoke the old certificate, please enable this "
 "option."
@@ -2537,7 +2559,7 @@ msgstr "إذا كنت ترغب في إلغاء الشهادة القديمة ت
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr "إذا كان متصفحك يدعم WebAuthn Passkey، ستظهر نافذة حوار."
 
-#: src/components/AutoCertForm/AutoCertForm.vue:113
+#: src/components/AutoCertForm/AutoCertForm.vue:250
 msgid ""
 "If your domain has CNAME records and you cannot obtain certificates, you "
 "need to enable this option."
@@ -2712,6 +2734,10 @@ msgstr "تنسيق رمز الأمان غير صالح"
 msgid "IP"
 msgstr "IP"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:102
+msgid "IP Certificate Notice"
+msgstr "إشعار شهادة IP"
+
 #: src/views/certificate/CertificateList/Certificate.vue:37
 msgid "Issue certificate"
 msgstr "إصدار شهادة"
@@ -2748,7 +2774,7 @@ msgstr ""
 msgid "Keepalive Timeout"
 msgstr "مهلة الاتصال المستمر"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:78
+#: src/components/AutoCertForm/AutoCertForm.vue:215
 #: src/views/certificate/CertificateList/certColumns.tsx:57
 msgid "Key Type"
 msgstr "نوع المفتاح"
@@ -2816,7 +2842,7 @@ msgstr "تركه فارغًا لن يغير شيئًا"
 msgid "Legacy recovery code not allowed since totp is not enabled"
 msgstr "لا يُسمح برمز الاسترداد القديم نظرًا لعدم تمكين TOTP"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:110
+#: src/components/AutoCertForm/AutoCertForm.vue:247
 msgid "Lego disable CNAME Support"
 msgstr "تعطيل دعم CNAME في Lego"
 
@@ -2902,12 +2928,12 @@ msgstr "سجل"
 #: src/language/generate.ts:21
 msgid ""
 "Log file %{log_path} is not a regular file. If you are using nginx-ui in "
-"docker container, please refer to https://nginxui.com/zh_CN/guide/config-"
-"nginx-log.html for more information."
+"docker container, please refer to "
+"https://nginxui.com/zh_CN/guide/config-nginx-log.html for more information."
 msgstr ""
 "ملف السجل %{log_path} ليس ملفًا عاديًا. إذا كنت تستخدم nginx-ui في حاوية "
-"Docker، يرجى الرجوع إلى https://nginxui.com/zh_CN/guide/config-nginx-log."
-"html لمزيد من المعلومات."
+"Docker، يرجى الرجوع إلى "
+"https://nginxui.com/zh_CN/guide/config-nginx-log.html لمزيد من المعلومات."
 
 #: src/routes/modules/nginx_log.ts:39 src/views/nginx_log/NginxLogList.vue:88
 msgid "Log List"
@@ -2931,19 +2957,19 @@ msgstr "تدوير السجلات"
 
 #: src/views/preference/tabs/LogrotateSettings.vue:13
 msgid ""
-"Logrotate, by default, is enabled in most mainstream Linux distributions for "
-"users who install Nginx UI on the host machine, so you don't need to modify "
-"the parameters on this page. For users who install Nginx UI using Docker "
-"containers, you can manually enable this option. The crontab task scheduler "
-"of Nginx UI will execute the logrotate command at the interval you set in "
-"minutes."
+"Logrotate, by default, is enabled in most mainstream Linux distributions "
+"for users who install Nginx UI on the host machine, so you don't need to "
+"modify the parameters on this page. For users who install Nginx UI using "
+"Docker containers, you can manually enable this option. The crontab task "
+"scheduler of Nginx UI will execute the logrotate command at the interval "
+"you set in minutes."
 msgstr ""
 "بشكل افتراضي، يتم تفعيل تدوير السجلات في معظم توزيعات لينكس الرئيسية "
 "للمستخدمين الذين يقومون بتثبيت واجهة Nginx UI على الجهاز المضيف، لذا لا "
-"تحتاج إلى تعديل معايير في هذه الصفحة. بالنسبة للمستخدمين الذين يقومون بتثبيت "
-"واجهة Nginx UI باستخدام حاويات Docker، يمكنك تمكين هذا الخيار يدويًا. سيقوم "
-"مجدول المهام crontab الخاص بواجهة Nginx UI بتنفيذ أمر تدوير السجلات في "
-"الفاصل الزمني الذي تحدده بالدقائق."
+"تحتاج إلى تعديل معايير في هذه الصفحة. بالنسبة للمستخدمين الذين يقومون "
+"بتثبيت واجهة Nginx UI باستخدام حاويات Docker، يمكنك تمكين هذا الخيار "
+"يدويًا. سيقوم مجدول المهام crontab الخاص بواجهة Nginx UI بتنفيذ أمر تدوير "
+"السجلات في الفاصل الزمني الذي تحدده بالدقائق."
 
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:51
 #: src/composables/useUpstreamStatus.ts:156
@@ -2968,7 +2994,7 @@ msgstr "تم تمكين وضع الصيانة بنجاح"
 msgid "Make certificate dir error: {0}"
 msgstr "خطأ في إنشاء مجلد الشهادة: {0}"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:53
+#: src/components/AutoCertForm/AutoCertForm.vue:143
 msgid ""
 "Make sure you have configured a reverse proxy for .well-known directory to "
 "HTTPChallengePort before obtaining the certificate."
@@ -3153,6 +3179,10 @@ msgstr "يوميًا في اليوم %{day} الساعة %{time}"
 msgid "Multi-line Directive"
 msgstr "توجيه متعدد الأسطر"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:175
+msgid "Must be a public IP address accessible from the internet"
+msgstr "يجب أن يكون عنوان IP عامًا يمكن الوصول إليه من الإنترنت"
+
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:38
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:56
 msgid "N/A"
@@ -3234,7 +3264,7 @@ msgstr "تم إصدار نسخة جديدة"
 #: src/views/certificate/components/DNSIssueCertificate.vue:183
 #: src/views/install/components/InstallView.vue:96
 #: src/views/site/site_add/SiteAdd.vue:131
-#: src/views/site/site_edit/components/Cert/ObtainCert.vue:214
+#: src/views/site/site_edit/components/Cert/ObtainCert.vue:219
 msgid "Next"
 msgstr "التالي"
 
@@ -3426,8 +3456,8 @@ msgstr "تمت استعادة تكوين Nginx UI"
 
 #: src/components/SystemRestore/SystemRestoreContent.vue:336
 msgid ""
-"Nginx UI configuration has been restored and will restart automatically in a "
-"few seconds."
+"Nginx UI configuration has been restored and will restart automatically in "
+"a few seconds."
 msgstr "تمت استعادة تكوين Nginx UI وسيتم إعادة التشغيل تلقائيًا خلال بضع ثوانٍ."
 
 #: src/language/generate.ts:28
@@ -3477,6 +3507,14 @@ msgstr "لم يتم تحديد أي سجلات"
 msgid "No servers configured"
 msgstr "لا توجد خوادم مُهيأة"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:115
+msgid ""
+"No specific IP address found in server_name configuration. Please specify "
+"the server IP address below for the certificate."
+msgstr ""
+"لم يتم العثور على عنوان IP محدد في تكوين server_name. يرجى تحديد عنوان IP "
+"الخادم أدناه للحصول على الشهادة."
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:103
 msgid "No upstreams configured"
 msgstr "لا توجد مصادر علوية مهيأة"
@@ -3525,11 +3563,15 @@ msgstr "غير موجود"
 msgid "Not Loaded"
 msgstr "غير محمل"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:209
+msgid "Not supported for IP certificates"
+msgstr "غير مدعوم لشهادات IP"
+
 #: src/components/CertInfo/CertInfo.vue:41
 msgid "Not Valid Before: %{date}"
 msgstr "غير صالح قبل: %{date}"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:39
+#: src/components/AutoCertForm/AutoCertForm.vue:129
 #: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgstr "ملاحظة"
@@ -3562,13 +3604,11 @@ msgstr "عدد عمليات العامل المتزامنة، يتم الضبط
 
 #: src/views/dashboard/components/ParamsOpt/ProxyCacheConfig.vue:315
 msgid "Number of files processed by cache loader at once"
-msgstr ""
-"عدد الملفات التي تتم معالجتها بواسطة محمل ذاكرة التخزين المؤقت في وقت واحد"
+msgstr "عدد الملفات التي تتم معالجتها بواسطة محمل ذاكرة التخزين المؤقت في وقت واحد"
 
 #: src/views/dashboard/components/ParamsOpt/ProxyCacheConfig.vue:253
 msgid "Number of files processed by cache manager at once"
-msgstr ""
-"عدد الملفات التي تتم معالجتها بواسطة مدير ذاكرة التخزين المؤقت في وقت واحد"
+msgstr "عدد الملفات التي تتم معالجتها بواسطة مدير ذاكرة التخزين المؤقت في وقت واحد"
 
 #: src/composables/usePerformanceMetrics.ts:129
 #: src/composables/usePerformanceMetrics.ts:169
@@ -3589,11 +3629,11 @@ msgstr "الحصول على شهادة"
 msgid "Obtaining certificate"
 msgstr "الحصول على الشهادة"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:100
+#: src/components/AutoCertForm/AutoCertForm.vue:237
 msgid "OCSP Must Staple"
 msgstr "يجب تثبيت OCSP"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:104
+#: src/components/AutoCertForm/AutoCertForm.vue:241
 msgid ""
 "OCSP Must Staple may cause errors for some users on first access using "
 "Firefox."
@@ -3845,8 +3885,15 @@ msgstr ""
 msgid ""
 "Please enter a name for the passkey you wish to create and click the OK "
 "button below."
-msgstr ""
-"يرجى إدخال اسم لمفتاح المرور الذي ترغب في إنشائه ثم انقر على زر موافق أدناه."
+msgstr "يرجى إدخال اسم لمفتاح المرور الذي ترغب في إنشائه ثم انقر على زر موافق أدناه."
+
+#: src/components/AutoCertForm/AutoCertForm.vue:77
+msgid "Please enter a valid IPv4 address (0-255 per octet)"
+msgstr "الرجاء إدخال عنوان IPv4 صحيح (0-255 لكل جزء)"
+
+#: src/components/AutoCertForm/AutoCertForm.vue:88
+msgid "Please enter a valid IPv4 or IPv6 address"
+msgstr "الرجاء إدخال عنوان IPv4 أو IPv6 صالح"
 
 #: src/components/PortScanner/PortScannerCompact.vue:85
 msgid "Please enter a valid port range"
@@ -3869,6 +3916,10 @@ msgstr "الرجاء إدخال رمز الأمان"
 msgid "Please enter the security token received during backup"
 msgstr "الرجاء إدخال رمز الأمان الذي تم استلامه أثناء النسخ الاحتياطي"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:59
+msgid "Please enter the server IP address"
+msgstr "الرجاء إدخال عنوان IP الخادم"
+
 #: src/language/curd.ts:24
 msgid "Please fill all fields correctly"
 msgstr "يرجى ملء جميع الحقول بشكل صحيح"
@@ -3883,7 +3934,7 @@ msgid ""
 "provider."
 msgstr "يرجى ملء بيانات اعتماد مصادقة API المقدمة من مزود DNS الخاص بك."
 
-#: src/components/AutoCertForm/AutoCertForm.vue:57
+#: src/components/AutoCertForm/AutoCertForm.vue:147
 msgid ""
 "Please first add credentials in Certification > DNS Credentials, and then "
 "select one of the credentialsbelow to request the API of the DNS provider."
@@ -3894,8 +3945,8 @@ msgstr ""
 #: src/components/Notification/notifications.ts:194
 #: src/language/constants.ts:59
 msgid ""
-"Please generate new recovery codes in the preferences immediately to prevent "
-"lockout."
+"Please generate new recovery codes in the preferences immediately to "
+"prevent lockout."
 msgstr "يرجى إنشاء رموز استرداد جديدة في التفضيلات على الفور لمنع الإغلاق."
 
 #: src/views/config/components/ConfigRightPanel/Basic.vue:27
@@ -3937,8 +3988,7 @@ msgid "Please log in."
 msgstr "الرجاء تسجيل الدخول."
 
 #: src/views/certificate/DNSCredential.vue:102
-msgid ""
-"Please note that the unit of time configurations below are all in seconds."
+msgid "Please note that the unit of time configurations below are all in seconds."
 msgstr "يرجى ملاحظة أن تكوين وحدات الوقت أدناه كلها بالثواني."
 
 #: src/views/install/components/InstallView.vue:102
@@ -3992,6 +4042,10 @@ msgstr "الرجاء كتابة نص التأكيد بالضبط"
 msgid "Port"
 msgstr "المنفذ"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:178
+msgid "Port 80 must be open for HTTP-01 challenge validation"
+msgstr "يجب أن يكون المنفذ 80 مفتوحًا للتحقق من تحدي HTTP-01"
+
 #: src/views/site/site_edit/components/RightPanel/RightPanel.vue:44
 #: src/views/stream/components/RightPanel/RightPanel.vue:25
 msgid "Port Scanner"
@@ -4016,6 +4070,14 @@ msgstr "تفضيل"
 msgid "Preparing lego configurations"
 msgstr "تحضير تكوينات Lego"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:185
+msgid "Private CA:"
+msgstr "CA الخاصة:"
+
+#: src/components/AutoCertForm/AutoCertForm.vue:181
+msgid "Private IPs (192.168.x.x, 10.x.x.x, 172.16-31.x.x) will fail"
+msgstr "ستفشل عناوين IP الخاصة (192.168.x.x، 10.x.x.x، 172.16-31.x.x)"
+
 #: src/views/certificate/components/CertificateFileUpload.vue:120
 #: src/views/certificate/components/CertificateFileUpload.vue:44
 msgid "private key"
@@ -4056,7 +4118,8 @@ msgstr "دليل محمي"
 #: src/views/preference/tabs/ServerSettings.vue:47
 msgid ""
 "Protocol configuration only takes effect when directly connecting. If using "
-"reverse proxy, please configure the protocol separately in the reverse proxy."
+"reverse proxy, please configure the protocol separately in the reverse "
+"proxy."
 msgstr ""
 "إعدادات البروتوكول تتأثر فقط عند الاتصال المباشر. إذا كنت تستخدم خادم وكيل "
 "عكسي، يرجى تكوين البروتوكول بشكل منفصل في خادم الوكيل العكسي."
@@ -4081,6 +4144,10 @@ msgstr "مرور الوكيل"
 msgid "Proxy Targets"
 msgstr "أهداف الوكيل"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:171
+msgid "Public CA Requirements:"
+msgstr "متطلبات CA العامة:"
+
 #: src/views/preference/tabs/NodeSettings.vue:46
 msgid "Public Security Number"
 msgstr "رقم الأمن العام"
@@ -4439,7 +4506,7 @@ msgstr "إبطال"
 msgid "Revoke cert error: {0}"
 msgstr "خطأ في إلغاء الشهادة: {0}"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:119
+#: src/components/AutoCertForm/AutoCertForm.vue:256
 msgid "Revoke Old Certificate"
 msgstr "إبطال الشهادة القديمة"
 
@@ -4725,6 +4792,8 @@ msgid ""
 "Select a predefined CA directory or enter a custom one. Leave blank to use "
 "the default CA directory."
 msgstr ""
+"حدد دليل CA مسبقًا أو أدخل دليلاً مخصصًا. اتركه فارغًا لاستخدام دليل CA "
+"الافتراضي."
 
 #: src/language/curd.ts:31
 msgid "Select all"
@@ -4732,7 +4801,7 @@ msgstr "تحديد الكل"
 
 #: src/views/certificate/ACMEUser.vue:43
 msgid "Select or enter a CA directory URL"
-msgstr ""
+msgstr "حدد أو أدخل عنوان URL لدليل CA"
 
 #: src/language/curd.ts:59
 msgid "Selected {count} files"
@@ -4772,6 +4841,10 @@ msgstr "خطأ في الخادم"
 msgid "Server Info"
 msgstr "معلومات الخادم"
 
+#: src/components/AutoCertForm/AutoCertForm.vue:157
+msgid "Server IP Address"
+msgstr "عنوان IP الخادم"
+
 #: src/views/dashboard/components/ParamsOpt/PerformanceConfig.vue:99
 msgid "Server Names Hash Bucket Size"
 msgstr "حجم جدول تجزئة أسماء الخوادم"
@@ -4826,19 +4899,19 @@ msgstr "تعيين موفر تحدي HTTP01"
 
 #: src/constants/errors/nginx_log.ts:8
 msgid ""
-"Settings.NginxLogSettings.AccessLogPath is empty, refer to https://nginxui."
-"com/guide/config-nginx.html for more information"
+"Settings.NginxLogSettings.AccessLogPath is empty, refer to "
+"https://nginxui.com/guide/config-nginx.html for more information"
 msgstr ""
-"إعدادات.Settings.NginxLogSettings.AccessLogPath فارغة، راجع https://nginxui."
-"com/guide/config-nginx.html لمزيد من المعلومات"
+"إعدادات.Settings.NginxLogSettings.AccessLogPath فارغة، راجع "
+"https://nginxui.com/guide/config-nginx.html لمزيد من المعلومات"
 
 #: src/constants/errors/nginx_log.ts:7
 msgid ""
-"Settings.NginxLogSettings.ErrorLogPath is empty, refer to https://nginxui."
-"com/guide/config-nginx.html for more information"
+"Settings.NginxLogSettings.ErrorLogPath is empty, refer to "
+"https://nginxui.com/guide/config-nginx.html for more information"
 msgstr ""
-"إعدادات.Settings.NginxLogSettings.ErrorLogPath فارغة، راجع https://nginxui."
-"com/guide/config-nginx.html لمزيد من المعلومات"
+"إعدادات.Settings.NginxLogSettings.ErrorLogPath فارغة، راجع "
+"https://nginxui.com/guide/config-nginx.html لمزيد من المعلومات"
 
 #: src/views/install/components/InstallView.vue:65
 msgid "Setup your Nginx UI"
@@ -5079,19 +5152,19 @@ msgstr "الأحد"
 msgid ""
 "Support communication with the backend through the Server-Sent Events "
 "protocol. If your Nginx UI is being used via an Nginx reverse proxy, please "
-"refer to this link to write the corresponding configuration file: https://"
-"nginxui.com/guide/nginx-proxy-example.html"
+"refer to this link to write the corresponding configuration file: "
+"https://nginxui.com/guide/nginx-proxy-example.html"
 msgstr ""
 "دعم الاتصال مع الخلفية من خلال بروتوكول Server-Sent Events. إذا كنت تستخدم "
-"واجهة Nginx UI عبر وكيل عكسي لـ Nginx، يرجى الرجوع إلى هذا الرابط لكتابة ملف "
-"التكوين المقابل: https://nginxui.com/guide/nginx-proxy-example.html"
+"واجهة Nginx UI عبر وكيل عكسي لـ Nginx، يرجى الرجوع إلى هذا الرابط لكتابة "
+"ملف التكوين المقابل: https://nginxui.com/guide/nginx-proxy-example.html"
 
 #: src/components/SelfCheck/tasks/frontend/websocket.ts:13
 msgid ""
 "Support communication with the backend through the WebSocket protocol. If "
-"your Nginx UI is being used via an Nginx reverse proxy, please refer to this "
-"link to write the corresponding configuration file: https://nginxui.com/"
-"guide/nginx-proxy-example.html"
+"your Nginx UI is being used via an Nginx reverse proxy, please refer to "
+"this link to write the corresponding configuration file: "
+"https://nginxui.com/guide/nginx-proxy-example.html"
 msgstr ""
 "دعم الاتصال مع الخلفية من خلال بروتوكول WebSocket. إذا كنت تستخدم واجهة "
 "Nginx عبر وكيل عكسي لـ Nginx، يرجى الرجوع إلى هذا الرابط لكتابة ملف التكوين "
@@ -5249,7 +5322,7 @@ msgstr "تم إرسال رسالة الاختبار بنجاح"
 msgid "Test S3 Connection"
 msgstr "اختبار اتصال S3"
 
-#: src/components/AutoCertForm/AutoCertForm.vue:49
+#: src/components/AutoCertForm/AutoCertForm.vue:139
 msgid ""
 "The certificate for the domain will be checked 30 minutes, and will be "
 "renewed if it has been more than 1 week or the period you set in settings "
@@ -5262,8 +5335,7 @@ msgstr ""
 msgid ""
 "The ICP Number should only contain letters, unicode, numbers, hyphens, "
 "dashes, colons, and dots."
-msgstr ""
-"يجب أن يحتوي رقم ICP على أحرف، يونيكود، أرقام، شرطات، نقاط، ونقطتين فقط."
+msgstr "يجب أن يحتوي رقم ICP على أحرف، يونيكود، أرقام، شرطات، نقاط، ونقطتين فقط."
 
 #: src/views/certificate/components/CertificateContentEditor.vue:96
 msgid "The input is not a SSL Certificate"
@@ -5275,10 +5347,11 @@ msgstr "المدخل ليس مفتاح شهادة SSL"
 
 #: src/constants/errors/nginx_log.ts:2
 msgid ""
-"The log path is not under the paths in settings.NginxSettings.LogDirWhiteList"
+"The log path is not under the paths in "
+"settings.NginxSettings.LogDirWhiteList"
 msgstr ""
-"مسار السجل ليس ضمن المسارات الموجودة في settings.NginxSettings."
-"LogDirWhiteList"
+"مسار السجل ليس ضمن المسارات الموجودة في "
+"settings.NginxSettings.LogDirWhiteList"
 
 #: src/views/preference/tabs/OpenAISettings.vue:23
 #: src/views/preference/tabs/OpenAISettings.vue:89
@@ -5290,8 +5363,7 @@ msgstr ""
 "فقط."
 
 #: src/views/preference/tabs/OpenAISettings.vue:90
-msgid ""
-"The model used for code completion, if not set, the chat model will be used."
+msgid "The model used for code completion, if not set, the chat model will be used."
 msgstr ""
 "النموذج المستخدم لإكمال التعليمات البرمجية، إذا لم يتم تعيينه، سيتم استخدام "
 "نموذج الدردشة."
@@ -5300,8 +5372,7 @@ msgstr ""
 msgid ""
 "The node name should only contain letters, unicode, numbers, hyphens, "
 "dashes, colons, and dots."
-msgstr ""
-"يجب أن يحتوي اسم العقدة على أحرف، يونيكود، أرقام، شرطات، نقاط، ونقطتين فقط."
+msgstr "يجب أن يحتوي اسم العقدة على أحرف، يونيكود، أرقام، شرطات، نقاط، ونقطتين فقط."
 
 #: src/views/site/site_add/SiteAdd.vue:96
 msgid "The parameter of server_name is required"
@@ -5332,7 +5403,7 @@ msgstr ""
 "إصدار واجهة Nginx البعيد غير متوافق مع إصدار واجهة Nginx المحلي. لتجنب "
 "الأخطاء المحتملة، يرجى ترقية واجهة Nginx البعيدة لتتطابق مع الإصدار المحلي."
 
-#: src/components/AutoCertForm/AutoCertForm.vue:44
+#: src/components/AutoCertForm/AutoCertForm.vue:134
 msgid ""
 "The server_name in the current configuration must be the domain name you "
 "need to get the certificate, supportmultiple domains."
@@ -5403,14 +5474,13 @@ msgid "This field should not be empty"
 msgstr "يجب ألا يكون هذا الحقل فارغًا"
 
 #: src/constants/form_errors.ts:6
-msgid ""
-"This field should only contain letters, unicode characters, numbers, and -_."
+msgid "This field should only contain letters, unicode characters, numbers, and -_."
 msgstr "يجب أن يحتوي هذا الحقل على حروف وأحرف يونيكود وأرقام و-_. فقط."
 
 #: src/language/curd.ts:46
 msgid ""
-"This field should only contain letters, unicode characters, numbers, and -"
-"_./:"
+"This field should only contain letters, unicode characters, numbers, and "
+"-_./:"
 msgstr "يجب أن يحتوي هذا الحقل فقط على أحرف وأحرف يونيكود وأرقام و -_./:"
 
 #: src/components/Notification/notifications.ts:94
@@ -5422,8 +5492,8 @@ msgid ""
 "This module provides Nginx request statistics, connection count, etc. data. "
 "After enabling it, you can view performance statistics"
 msgstr ""
-"توفر هذه الوحدة إحصائيات طلبات Nginx وعدد الاتصالات وما إلى ذلك من البيانات. "
-"بعد تمكينها، يمكنك عرض إحصائيات الأداء"
+"توفر هذه الوحدة إحصائيات طلبات Nginx وعدد الاتصالات وما إلى ذلك من "
+"البيانات. بعد تمكينها، يمكنك عرض إحصائيات الأداء"
 
 #: src/views/certificate/components/RemoveCert.vue:106
 msgid ""
@@ -5433,6 +5503,26 @@ msgstr ""
 "هذه العملية ستزيل الشهادة من قاعدة البيانات فقط. لن يتم حذف ملفات الشهادة "
 "على نظام الملفات."
 
+#: src/components/AutoCertForm/AutoCertForm.vue:107
+msgid ""
+"This site is configured as a default server (default_server) for HTTPS "
+"(port 443). IP certificates require Certificate Authority (CA) support and "
+"may not be available with all ACME providers."
+msgstr ""
+"تم تكوين هذا الموقع كخادم افتراضي (default_server) لـ HTTPS (المنفذ 443). "
+"تتطلب شهادات IP دعمًا من سلطة الشهادات (CA) وقد لا تكون متاحة مع جميع موفري "
+"ACME."
+
+#: src/components/AutoCertForm/AutoCertForm.vue:111
+msgid ""
+"This site uses wildcard server name (_) which typically indicates an "
+"IP-based certificate. IP certificates require Certificate Authority (CA) "
+"support and may not be available with all ACME providers."
+msgstr ""
+"يستخدم هذا الموقع اسم خادم شامل (_) والذي يشير عادةً إلى شهادة قائمة على "
+"عنوان IP. تتطلب شهادات IP دعمًا من سلطة الشهادات (CA) وقد لا تكون متاحة مع "
+"جميع موفري ACME."
+
 #: src/views/backup/components/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -5464,12 +5554,11 @@ msgid ""
 "This will restore configuration files and database. Nginx UI will restart "
 "after the restoration is complete."
 msgstr ""
-"سيؤدي هذا إلى استعادة ملفات التكوين وقاعدة البيانات. سيعاد تشغيل واجهة Nginx "
-"بعد اكتمال الاستعادة."
+"سيؤدي هذا إلى استعادة ملفات التكوين وقاعدة البيانات. سيعاد تشغيل واجهة "
+"Nginx بعد اكتمال الاستعادة."
 
 #: src/views/environments/list/BatchUpgrader.vue:186
-msgid ""
-"This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
+msgid "This will upgrade or reinstall the Nginx UI on %{nodeNames} to %{version}."
 msgstr "سيتم ترقية أو إعادة تثبيت Nginx UI على %{nodeNames} إلى %{version}."
 
 #: src/views/preference/tabs/AuthSettings.vue:92
@@ -5523,8 +5612,8 @@ msgstr ""
 #: src/views/site/site_edit/components/EnableTLS/EnableTLS.vue:15
 msgid ""
 "To make sure the certification auto-renewal can work normally, we need to "
-"add a location which can proxy the request from authority to backend, and we "
-"need to save this file and reload the Nginx. Are you sure you want to "
+"add a location which can proxy the request from authority to backend, and "
+"we need to save this file and reload the Nginx. Are you sure you want to "
 "continue?"
 msgstr ""
 "لضمان عمل تجديد الشهادة التلقائي بشكل طبيعي، نحتاج إلى إضافة موقع يمكنه "
@@ -5537,9 +5626,9 @@ msgid ""
 "provide an OpenAI-compatible API endpoint, so just set the baseUrl to your "
 "local API."
 msgstr ""
-"لاستخدام نموذج كبير محلي، قم بنشره باستخدام ollama أو vllm أو lmdeploy. توفر "
-"هذه الأدوات نقطة نهاية API متوافقة مع OpenAI، لذا ما عليك سوى تعيين baseUrl "
-"إلى API المحلي الخاص بك."
+"لاستخدام نموذج كبير محلي، قم بنشره باستخدام ollama أو vllm أو lmdeploy. "
+"توفر هذه الأدوات نقطة نهاية API متوافقة مع OpenAI، لذا ما عليك سوى تعيين "
+"baseUrl إلى API المحلي الخاص بك."
 
 #: src/views/dashboard/NginxDashBoard.vue:57
 msgid "Toggle failed"
@@ -5826,8 +5915,18 @@ msgid ""
 "you have a valid backup file and security token, and carefully select what "
 "to restore."
 msgstr ""
-"تحذير: ستقوم عملية الاستعادة بالكتابة فوق التكوينات الحالية. تأكد من أن لديك "
-"ملف نسخ احتياطي صالحًا ورمزًا أمنيًا، واختر بعناية ما تريد استعادته."
+"تحذير: ستقوم عملية الاستعادة بالكتابة فوق التكوينات الحالية. تأكد من أن "
+"لديك ملف نسخ احتياطي صالحًا ورمزًا أمنيًا، واختر بعناية ما تريد استعادته."
+
+#: src/components/AutoCertForm/AutoCertForm.vue:82
+msgid ""
+"Warning: This appears to be a private IP address. Public CAs like Let's "
+"Encrypt cannot issue certificates for private IPs. Use a public IP address "
+"or consider using a private CA."
+msgstr ""
+"تحذير: يبدو أن هذا عنوان IP خاص. لا يمكن لسلطات التصديق العامة مثل Let's "
+"Encrypt إصدار شهادات لعناوين IP الخاصة. استخدم عنوان IP عام أو فكر في "
+"استخدام سلطة تصديق خاصة."
 
 #: src/views/certificate/DNSCredential.vue:96
 msgid ""
@@ -5837,8 +5936,8 @@ msgstr "سنضيف سجل أو أكثر من سجلات TXT إلى سجلات DN
 
 #: src/views/site/site_edit/components/Cert/ObtainCert.vue:140
 msgid ""
-"We will remove the HTTPChallenge configuration from this file and reload the "
-"Nginx. Are you sure you want to continue?"
+"We will remove the HTTPChallenge configuration from this file and reload "
+"the Nginx. Are you sure you want to continue?"
 msgstr ""
 "سنقوم بإزالة تكوين HTTPChallenge من هذا الملف وإعادة تحميل Nginx. هل أنت "
 "متأكد أنك تريد المتابعة؟"
@@ -5952,11 +6051,11 @@ msgstr "نعم"
 
 #: src/views/terminal/Terminal.vue:132
 msgid ""
-"You are accessing this terminal over an insecure HTTP connection on a non-"
-"localhost domain. This may expose sensitive information."
+"You are accessing this terminal over an insecure HTTP connection on a "
+"non-localhost domain. This may expose sensitive information."
 msgstr ""
-"أنت تتصل بهذا الطرف عبر اتصال HTTP غير آمن في نطاق غير محلي. قد يؤدي هذا إلى "
-"كشف معلومات حساسة."
+"أنت تتصل بهذا الطرف عبر اتصال HTTP غير آمن في نطاق غير محلي. قد يؤدي هذا "
+"إلى كشف معلومات حساسة."
 
 #: src/constants/errors/config.ts:8
 msgid "You are not allowed to delete a file outside of the nginx config path"
@@ -5985,8 +6084,7 @@ msgid ""
 msgstr "لم تقم بتكوين إعدادات Webauthn، لذا لا يمكنك إضافة مفتاح مرور."
 
 #: src/views/preference/components/AuthSettings/RecoveryCodes.vue:81
-msgid ""
-"You have not enabled 2FA yet. Please enable 2FA to generate recovery codes."
+msgid "You have not enabled 2FA yet. Please enable 2FA to generate recovery codes."
 msgstr ""
 "لم تقم بتمكين المصادقة الثنائية بعد. يرجى تمكين المصادقة الثنائية لإنشاء "
 "رموز الاسترداد."
@@ -6108,12 +6206,12 @@ msgstr "مفاتيح المرور الخاصة بك"
 
 #~ msgid ""
 #~ "Check if /var/run/docker.sock exists. If you are using Nginx UI Official "
-#~ "Docker Image, please make sure the docker socket is mounted like this: `-"
-#~ "v /var/run/docker.sock:/var/run/docker.sock`."
+#~ "Docker Image, please make sure the docker socket is mounted like this: `-v "
+#~ "/var/run/docker.sock:/var/run/docker.sock`."
 #~ msgstr ""
 #~ "تحقق مما إذا كان /var/run/docker.sock موجودًا. إذا كنت تستخدم صورة Docker "
-#~ "الرسمية لـ Nginx UI، يرجى التأكد من أن مقبس Docker مثبت بهذه الطريقة: `-"
-#~ "v /var/run/docker.sock:/var/run/docker.sock`."
+#~ "الرسمية لـ Nginx UI، يرجى التأكد من أن مقبس Docker مثبت بهذه الطريقة: `-v "
+#~ "/var/run/docker.sock:/var/run/docker.sock`."
 
 #~ msgid "Check if the nginx access log path exists"
 #~ msgstr "تحقق مما إذا كان مسار سجل الوصول لـ nginx موجودًا"
@@ -6152,8 +6250,8 @@ msgstr "مفاتيح المرور الخاصة بك"
 
 #, fuzzy
 #~ msgid ""
-#~ "When you enable/disable, delete, or save this stream, the nodes set in "
-#~ "the Node Group and the nodes selected below will be synchronized."
+#~ "When you enable/disable, delete, or save this stream, the nodes set in the "
+#~ "Node Group and the nodes selected below will be synchronized."
 #~ msgstr ""
 #~ "عند تفعيل/تعطيل، حذف، أو حفظ هذا الموقع، سيتم مزامنة العقد المحددة في فئة "
 #~ "الموقع والعقد المحددة أدناه."
@@ -6220,15 +6318,12 @@ msgstr "مفاتيح المرور الخاصة بك"
 #~ msgid "Please upgrade the remote Nginx UI to the latest version"
 #~ msgstr "يرجى ترقية واجهة Nginx البعيدة إلى أحدث إصدار"
 
-#~ msgid ""
-#~ "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: "
-#~ "%{resp}"
+#~ msgid "Rename %{orig_path} to %{new_path} on %{env_name} failed, response: %{resp}"
 #~ msgstr ""
 #~ "فشل إعادة تسمية %{orig_path} إلى %{new_path} على %{env_name}، الاستجابة: "
 #~ "%{resp}"
 
-#~ msgid ""
-#~ "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
+#~ msgid "Rename Site %{site} to %{new_site} on %{node} error, response: %{resp}"
 #~ msgstr ""
 #~ "خطأ في إعادة تسمية الموقع %{site} إلى %{new_site} على %{node}، الاستجابة: "
 #~ "%{resp}"
@@ -6243,17 +6338,15 @@ msgstr "مفاتيح المرور الخاصة بك"
 #~ "فشل مزامنة الشهادة %{cert_name} إلى %{env_name}، يرجى ترقية واجهة Nginx "
 #~ "البعيدة إلى أحدث إصدار"
 
-#~ msgid ""
-#~ "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
+#~ msgid "Sync Certificate %{cert_name} to %{env_name} failed, response: %{resp}"
 #~ msgstr "فشل مزامنة الشهادة %{cert_name} إلى %{env_name}، الاستجابة: %{resp}"
 
 #~ msgid "Sync config %{config_name} to %{env_name} failed, response: %{resp}"
-#~ msgstr ""
-#~ "فشل مزامنة التكوين %{config_name} إلى %{env_name}، الاستجابة: %{resp}"
+#~ msgstr "فشل مزامنة التكوين %{config_name} إلى %{env_name}، الاستجابة: %{resp}"
 
 #~ msgid ""
-#~ "If you lose your mobile phone, you can use the recovery code to reset "
-#~ "your 2FA."
+#~ "If you lose your mobile phone, you can use the recovery code to reset your "
+#~ "2FA."
 #~ msgstr ""
 #~ "إذا فقدت هاتفك المحمول، يمكنك استخدام رمز الاسترداد لإعادة تعيين المصادقة "
 #~ "الثنائية."
@@ -6261,8 +6354,7 @@ msgstr "مفاتيح المرور الخاصة بك"
 #~ msgid "Recovery Code:"
 #~ msgstr "رمز الاسترداد:"
 
-#~ msgid ""
-#~ "The recovery code is only displayed once, please save it in a safe place."
+#~ msgid "The recovery code is only displayed once, please save it in a safe place."
 #~ msgstr "رمز الاسترداد يُعرض مرة واحدة فقط، يرجى حفظه في مكان آمن."
 
 #~ msgid "Can't scan? Use text key binding"
@@ -6272,5 +6364,4 @@ msgstr "مفاتيح المرور الخاصة بك"
 #~ msgstr "اسم المستخدم أو كلمة المرور غير صحيحة"
 
 #~ msgid "Too many login failed attempts, please try again later"
-#~ msgstr ""
-#~ "عدد كبير جدًا من محاولات تسجيل الدخول الفاشلة، يرجى المحاولة مرة أخرى لاحقًا"
+#~ msgstr "عدد كبير جدًا من محاولات تسجيل الدخول الفاشلة، يرجى المحاولة مرة أخرى لاحقًا"

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 236 - 178
app/src/language/de_DE/app.po


+ 109 - 17
app/src/language/en/app.po

@@ -225,6 +225,11 @@ msgid ""
 "certificate application will fail."
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:188
+msgid ""
+"Any reachable IP address can be used with private Certificate Authorities"
+msgstr ""
+
 #: src/views/preference/tabs/OpenAISettings.vue:32
 msgid "API Base Url"
 msgstr ""
@@ -749,7 +754,7 @@ msgstr ""
 msgid "Challenge error: {0}"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:66
+#: src/components/AutoCertForm/AutoCertForm.vue:197
 msgid "Challenge Method"
 msgstr ""
 
@@ -1486,11 +1491,11 @@ msgstr ""
 msgid "DNS Provider"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:73
+#: src/components/AutoCertForm/AutoCertForm.vue:207
 msgid "DNS01"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:103
+#: src/components/AutoCertForm/AutoCertForm.vue:240
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr ""
 
@@ -1778,6 +1783,10 @@ msgstr ""
 msgid "Enter domain name"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:162
+msgid "Enter server IP address (e.g., 203.0.113.1 or 2001:db8::1)"
+msgstr ""
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:122
 msgid "Enter your domain"
 msgstr ""
@@ -2310,6 +2319,18 @@ msgstr ""
 msgid "For Chinese user: https://cloud.nginxui.com/"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:119
+msgid ""
+"For IP-based certificate configurations, only HTTP-01 challenge method is "
+"supported. DNS-01 challenge is not compatible with IP-based certificates."
+msgstr ""
+
+#: src/components/AutoCertForm/AutoCertForm.vue:167
+msgid ""
+"For IP-based certificates, please specify the server IP address that will be "
+"included in the certificate."
+msgstr ""
+
 #: src/constants/errors/middleware.ts:4
 msgid "Form parse failed"
 msgstr ""
@@ -2434,7 +2455,7 @@ msgstr ""
 msgid "HTTP Challenge Port"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:70
+#: src/components/AutoCertForm/AutoCertForm.vue:201
 msgid "HTTP01"
 msgstr ""
 
@@ -2452,7 +2473,7 @@ msgid ""
 "ban threshold minutes, the ip will be banned for a period of time."
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:122
+#: src/components/AutoCertForm/AutoCertForm.vue:259
 msgid ""
 "If you want to automatically revoke the old certificate, please enable this "
 "option."
@@ -2462,7 +2483,7 @@ msgstr ""
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:113
+#: src/components/AutoCertForm/AutoCertForm.vue:250
 msgid ""
 "If your domain has CNAME records and you cannot obtain certificates, you "
 "need to enable this option."
@@ -2631,6 +2652,10 @@ msgstr ""
 msgid "IP"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:102
+msgid "IP Certificate Notice"
+msgstr ""
+
 #: src/views/certificate/CertificateList/Certificate.vue:37
 msgid "Issue certificate"
 msgstr ""
@@ -2665,7 +2690,7 @@ msgstr ""
 msgid "Keepalive Timeout"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:78
+#: src/components/AutoCertForm/AutoCertForm.vue:215
 #: src/views/certificate/CertificateList/certColumns.tsx:57
 msgid "Key Type"
 msgstr ""
@@ -2733,7 +2758,7 @@ msgstr ""
 msgid "Legacy recovery code not allowed since totp is not enabled"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:110
+#: src/components/AutoCertForm/AutoCertForm.vue:247
 msgid "Lego disable CNAME Support"
 msgstr ""
 
@@ -2876,7 +2901,7 @@ msgstr ""
 msgid "Make certificate dir error: {0}"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:53
+#: src/components/AutoCertForm/AutoCertForm.vue:143
 msgid ""
 "Make sure you have configured a reverse proxy for .well-known directory to "
 "HTTPChallengePort before obtaining the certificate."
@@ -3059,6 +3084,10 @@ msgstr ""
 msgid "Multi-line Directive"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:175
+msgid "Must be a public IP address accessible from the internet"
+msgstr ""
+
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:38
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:56
 msgid "N/A"
@@ -3140,7 +3169,7 @@ msgstr ""
 #: src/views/certificate/components/DNSIssueCertificate.vue:183
 #: src/views/install/components/InstallView.vue:96
 #: src/views/site/site_add/SiteAdd.vue:131
-#: src/views/site/site_edit/components/Cert/ObtainCert.vue:214
+#: src/views/site/site_edit/components/Cert/ObtainCert.vue:219
 msgid "Next"
 msgstr ""
 
@@ -3383,6 +3412,12 @@ msgstr ""
 msgid "No servers configured"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:115
+msgid ""
+"No specific IP address found in server_name configuration. Please specify "
+"the server IP address below for the certificate."
+msgstr ""
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:103
 msgid "No upstreams configured"
 msgstr ""
@@ -3431,11 +3466,15 @@ msgstr ""
 msgid "Not Loaded"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:209
+msgid "Not supported for IP certificates"
+msgstr ""
+
 #: src/components/CertInfo/CertInfo.vue:41
 msgid "Not Valid Before: %{date}"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:39
+#: src/components/AutoCertForm/AutoCertForm.vue:129
 #: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgstr ""
@@ -3491,11 +3530,11 @@ msgstr ""
 msgid "Obtaining certificate"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:100
+#: src/components/AutoCertForm/AutoCertForm.vue:237
 msgid "OCSP Must Staple"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:104
+#: src/components/AutoCertForm/AutoCertForm.vue:241
 msgid ""
 "OCSP Must Staple may cause errors for some users on first access using "
 "Firefox."
@@ -3742,6 +3781,14 @@ msgid ""
 "button below."
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:77
+msgid "Please enter a valid IPv4 address (0-255 per octet)"
+msgstr ""
+
+#: src/components/AutoCertForm/AutoCertForm.vue:88
+msgid "Please enter a valid IPv4 or IPv6 address"
+msgstr ""
+
 #: src/components/PortScanner/PortScannerCompact.vue:85
 msgid "Please enter a valid port range"
 msgstr ""
@@ -3763,6 +3810,10 @@ msgstr ""
 msgid "Please enter the security token received during backup"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:59
+msgid "Please enter the server IP address"
+msgstr ""
+
 #: src/language/curd.ts:24
 msgid "Please fill all fields correctly"
 msgstr ""
@@ -3777,7 +3828,7 @@ msgid ""
 "provider."
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:57
+#: src/components/AutoCertForm/AutoCertForm.vue:147
 msgid ""
 "Please first add credentials in Certification > DNS Credentials, and then "
 "select one of the credentialsbelow to request the API of the DNS provider."
@@ -3884,6 +3935,10 @@ msgstr ""
 msgid "Port"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:178
+msgid "Port 80 must be open for HTTP-01 challenge validation"
+msgstr ""
+
 #: src/views/site/site_edit/components/RightPanel/RightPanel.vue:44
 #: src/views/stream/components/RightPanel/RightPanel.vue:25
 msgid "Port Scanner"
@@ -3908,6 +3963,14 @@ msgstr ""
 msgid "Preparing lego configurations"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:185
+msgid "Private CA:"
+msgstr ""
+
+#: src/components/AutoCertForm/AutoCertForm.vue:181
+msgid "Private IPs (192.168.x.x, 10.x.x.x, 172.16-31.x.x) will fail"
+msgstr ""
+
 #: src/views/certificate/components/CertificateFileUpload.vue:120
 #: src/views/certificate/components/CertificateFileUpload.vue:44
 msgid "private key"
@@ -3971,6 +4034,10 @@ msgstr ""
 msgid "Proxy Targets"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:171
+msgid "Public CA Requirements:"
+msgstr ""
+
 #: src/views/preference/tabs/NodeSettings.vue:46
 msgid "Public Security Number"
 msgstr ""
@@ -4325,7 +4392,7 @@ msgstr ""
 msgid "Revoke cert error: {0}"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:119
+#: src/components/AutoCertForm/AutoCertForm.vue:256
 msgid "Revoke Old Certificate"
 msgstr ""
 
@@ -4656,6 +4723,10 @@ msgstr ""
 msgid "Server Info"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:157
+msgid "Server IP Address"
+msgstr ""
+
 #: src/views/dashboard/components/ParamsOpt/PerformanceConfig.vue:99
 msgid "Server Names Hash Bucket Size"
 msgstr ""
@@ -5119,7 +5190,7 @@ msgstr ""
 msgid "Test S3 Connection"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:49
+#: src/components/AutoCertForm/AutoCertForm.vue:139
 msgid ""
 "The certificate for the domain will be checked 30 minutes, and will be "
 "renewed if it has been more than 1 week or the period you set in settings "
@@ -5188,7 +5259,7 @@ msgid ""
 "match the local version."
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:44
+#: src/components/AutoCertForm/AutoCertForm.vue:134
 msgid ""
 "The server_name in the current configuration must be the domain name you "
 "need to get the certificate, supportmultiple domains."
@@ -5280,6 +5351,20 @@ msgid ""
 "certificate files on the file system will not be deleted."
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:107
+msgid ""
+"This site is configured as a default server (default_server) for HTTPS (port "
+"443). IP certificates require Certificate Authority (CA) support and may not "
+"be available with all ACME providers."
+msgstr ""
+
+#: src/components/AutoCertForm/AutoCertForm.vue:111
+msgid ""
+"This site uses wildcard server name (_) which typically indicates an IP-"
+"based certificate. IP certificates require Certificate Authority (CA) "
+"support and may not be available with all ACME providers."
+msgstr ""
+
 #: src/views/backup/components/BackupCreator.vue:141
 msgid ""
 "This token will only be shown once and cannot be retrieved later. Please "
@@ -5654,6 +5739,13 @@ msgid ""
 "to restore."
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:82
+msgid ""
+"Warning: This appears to be a private IP address. Public CAs like Let's "
+"Encrypt cannot issue certificates for private IPs. Use a public IP address "
+"or consider using a private CA."
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:96
 msgid ""
 "We will add one or more TXT records to the DNS records of your domain for "

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 266 - 164
app/src/language/es/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 265 - 182
app/src/language/fr_FR/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 222 - 238
app/src/language/ja_JP/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 241 - 231
app/src/language/ko_KR/app.po


+ 93 - 17
app/src/language/messages.pot

@@ -231,6 +231,10 @@ msgstr ""
 msgid "All selected subdomains must belong to the same DNS Provider, otherwise the certificate application will fail."
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:188
+msgid "Any reachable IP address can be used with private Certificate Authorities"
+msgstr ""
+
 #: src/views/preference/tabs/OpenAISettings.vue:32
 msgid "API Base Url"
 msgstr ""
@@ -756,7 +760,7 @@ msgstr ""
 msgid "Challenge error: {0}"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:66
+#: src/components/AutoCertForm/AutoCertForm.vue:197
 msgid "Challenge Method"
 msgstr ""
 
@@ -1466,11 +1470,11 @@ msgstr ""
 msgid "DNS Provider"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:73
+#: src/components/AutoCertForm/AutoCertForm.vue:207
 msgid "DNS01"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:103
+#: src/components/AutoCertForm/AutoCertForm.vue:240
 msgid "Do not enable this option unless you are sure that you need it."
 msgstr ""
 
@@ -1757,6 +1761,10 @@ msgstr ""
 msgid "Enter domain name"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:162
+msgid "Enter server IP address (e.g., 203.0.113.1 or 2001:db8::1)"
+msgstr ""
+
 #: src/views/certificate/components/DNSIssueCertificate.vue:122
 msgid "Enter your domain"
 msgstr ""
@@ -2285,6 +2293,14 @@ msgstr ""
 msgid "For Chinese user: https://cloud.nginxui.com/"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:119
+msgid "For IP-based certificate configurations, only HTTP-01 challenge method is supported. DNS-01 challenge is not compatible with IP-based certificates."
+msgstr ""
+
+#: src/components/AutoCertForm/AutoCertForm.vue:167
+msgid "For IP-based certificates, please specify the server IP address that will be included in the certificate."
+msgstr ""
+
 #: src/constants/errors/middleware.ts:4
 msgid "Form parse failed"
 msgstr ""
@@ -2409,7 +2425,7 @@ msgstr ""
 msgid "HTTP Challenge Port"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:70
+#: src/components/AutoCertForm/AutoCertForm.vue:201
 msgid "HTTP01"
 msgstr ""
 
@@ -2425,7 +2441,7 @@ msgstr ""
 msgid "If the number of login failed attempts from a ip reach the max attempts in ban threshold minutes, the ip will be banned for a period of time."
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:122
+#: src/components/AutoCertForm/AutoCertForm.vue:259
 msgid "If you want to automatically revoke the old certificate, please enable this option."
 msgstr ""
 
@@ -2433,7 +2449,7 @@ msgstr ""
 msgid "If your browser supports WebAuthn Passkey, a dialog box will appear."
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:113
+#: src/components/AutoCertForm/AutoCertForm.vue:250
 msgid "If your domain has CNAME records and you cannot obtain certificates, you need to enable this option."
 msgstr ""
 
@@ -2597,6 +2613,10 @@ msgstr ""
 msgid "IP"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:102
+msgid "IP Certificate Notice"
+msgstr ""
+
 #: src/views/certificate/CertificateList/Certificate.vue:37
 msgid "Issue certificate"
 msgstr ""
@@ -2629,7 +2649,7 @@ msgstr ""
 msgid "Keepalive Timeout"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:78
+#: src/components/AutoCertForm/AutoCertForm.vue:215
 #: src/views/certificate/CertificateList/certColumns.tsx:57
 msgid "Key Type"
 msgstr ""
@@ -2698,7 +2718,7 @@ msgstr ""
 msgid "Legacy recovery code not allowed since totp is not enabled"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:110
+#: src/components/AutoCertForm/AutoCertForm.vue:247
 msgid "Lego disable CNAME Support"
 msgstr ""
 
@@ -2835,7 +2855,7 @@ msgstr ""
 msgid "Make certificate dir error: {0}"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:53
+#: src/components/AutoCertForm/AutoCertForm.vue:143
 msgid "Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort before obtaining the certificate."
 msgstr ""
 
@@ -3019,6 +3039,10 @@ msgstr ""
 msgid "Multi-line Directive"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:175
+msgid "Must be a public IP address accessible from the internet"
+msgstr ""
+
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:38
 #: src/components/UpstreamDetailModal/UpstreamDetailModal.vue:56
 msgid "N/A"
@@ -3101,7 +3125,7 @@ msgstr ""
 #: src/views/certificate/components/DNSIssueCertificate.vue:183
 #: src/views/install/components/InstallView.vue:96
 #: src/views/site/site_add/SiteAdd.vue:131
-#: src/views/site/site_edit/components/Cert/ObtainCert.vue:214
+#: src/views/site/site_edit/components/Cert/ObtainCert.vue:219
 msgid "Next"
 msgstr ""
 
@@ -3347,6 +3371,10 @@ msgstr ""
 msgid "No servers configured"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:115
+msgid "No specific IP address found in server_name configuration. Please specify the server IP address below for the certificate."
+msgstr ""
+
 #: src/components/NgxConfigEditor/NgxUpstream.vue:103
 msgid "No upstreams configured"
 msgstr ""
@@ -3396,11 +3424,15 @@ msgstr ""
 msgid "Not Loaded"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:209
+msgid "Not supported for IP certificates"
+msgstr ""
+
 #: src/components/CertInfo/CertInfo.vue:41
 msgid "Not Valid Before: %{date}"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:39
+#: src/components/AutoCertForm/AutoCertForm.vue:129
 #: src/views/certificate/DNSCredential.vue:89
 msgid "Note"
 msgstr ""
@@ -3454,11 +3486,11 @@ msgstr ""
 msgid "Obtaining certificate"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:100
+#: src/components/AutoCertForm/AutoCertForm.vue:237
 msgid "OCSP Must Staple"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:104
+#: src/components/AutoCertForm/AutoCertForm.vue:241
 msgid "OCSP Must Staple may cause errors for some users on first access using Firefox."
 msgstr ""
 
@@ -3700,6 +3732,14 @@ msgstr ""
 msgid "Please enter a name for the passkey you wish to create and click the OK button below."
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:77
+msgid "Please enter a valid IPv4 address (0-255 per octet)"
+msgstr ""
+
+#: src/components/AutoCertForm/AutoCertForm.vue:88
+msgid "Please enter a valid IPv4 or IPv6 address"
+msgstr ""
+
 #: src/components/PortScanner/PortScannerCompact.vue:85
 msgid "Please enter a valid port range"
 msgstr ""
@@ -3721,6 +3761,10 @@ msgstr ""
 msgid "Please enter the security token received during backup"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:59
+msgid "Please enter the server IP address"
+msgstr ""
+
 #: src/language/curd.ts:24
 msgid "Please fill all fields correctly"
 msgstr ""
@@ -3733,7 +3777,7 @@ msgstr ""
 msgid "Please fill in the API authentication credentials provided by your DNS provider."
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:57
+#: src/components/AutoCertForm/AutoCertForm.vue:147
 msgid "Please first add credentials in Certification > DNS Credentials, and then select one of the credentialsbelow to request the API of the DNS provider."
 msgstr ""
 
@@ -3833,6 +3877,10 @@ msgstr ""
 msgid "Port"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:178
+msgid "Port 80 must be open for HTTP-01 challenge validation"
+msgstr ""
+
 #: src/views/site/site_edit/components/RightPanel/RightPanel.vue:44
 #: src/views/stream/components/RightPanel/RightPanel.vue:25
 msgid "Port Scanner"
@@ -3859,6 +3907,14 @@ msgstr ""
 msgid "Preparing lego configurations"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:185
+msgid "Private CA:"
+msgstr ""
+
+#: src/components/AutoCertForm/AutoCertForm.vue:181
+msgid "Private IPs (192.168.x.x, 10.x.x.x, 172.16-31.x.x) will fail"
+msgstr ""
+
 #: src/views/certificate/components/CertificateFileUpload.vue:120
 #: src/views/certificate/components/CertificateFileUpload.vue:44
 msgid "private key"
@@ -3921,6 +3977,10 @@ msgstr ""
 msgid "Proxy Targets"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:171
+msgid "Public CA Requirements:"
+msgstr ""
+
 #: src/views/preference/tabs/NodeSettings.vue:46
 msgid "Public Security Number"
 msgstr ""
@@ -4273,7 +4333,7 @@ msgstr ""
 msgid "Revoke cert error: {0}"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:119
+#: src/components/AutoCertForm/AutoCertForm.vue:256
 msgid "Revoke Old Certificate"
 msgstr ""
 
@@ -4606,6 +4666,10 @@ msgstr ""
 msgid "Server Info"
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:157
+msgid "Server IP Address"
+msgstr ""
+
 #: src/views/dashboard/components/ParamsOpt/PerformanceConfig.vue:99
 msgid "Server Names Hash Bucket Size"
 msgstr ""
@@ -5063,7 +5127,7 @@ msgstr ""
 msgid "Test S3 Connection"
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:49
+#: src/components/AutoCertForm/AutoCertForm.vue:139
 msgid "The certificate for the domain will be checked 30 minutes, and will be renewed if it has been more than 1 week or the period you set in settings since it was last issued."
 msgstr ""
 
@@ -5116,7 +5180,7 @@ msgstr ""
 msgid "The remote Nginx UI version is not compatible with the local Nginx UI version. To avoid potential errors, please upgrade the remote Nginx UI to match the local version."
 msgstr ""
 
-#: src/components/AutoCertForm/AutoCertForm.vue:44
+#: src/components/AutoCertForm/AutoCertForm.vue:134
 msgid "The server_name in the current configuration must be the domain name you need to get the certificate, supportmultiple domains."
 msgstr ""
 
@@ -5199,6 +5263,14 @@ msgstr ""
 msgid "This operation will only remove the certificate from the database. The certificate files on the file system will not be deleted."
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:107
+msgid "This site is configured as a default server (default_server) for HTTPS (port 443). IP certificates require Certificate Authority (CA) support and may not be available with all ACME providers."
+msgstr ""
+
+#: src/components/AutoCertForm/AutoCertForm.vue:111
+msgid "This site uses wildcard server name (_) which typically indicates an IP-based certificate. IP certificates require Certificate Authority (CA) support and may not be available with all ACME providers."
+msgstr ""
+
 #: src/views/backup/components/BackupCreator.vue:141
 msgid "This token will only be shown once and cannot be retrieved later. Please make sure to save it in a secure location."
 msgstr ""
@@ -5554,6 +5626,10 @@ msgstr ""
 msgid "Warning: Restore operation will overwrite current configurations. Make sure you have a valid backup file and security token, and carefully select what to restore."
 msgstr ""
 
+#: src/components/AutoCertForm/AutoCertForm.vue:82
+msgid "Warning: This appears to be a private IP address. Public CAs like Let's Encrypt cannot issue certificates for private IPs. Use a public IP address or consider using a private CA."
+msgstr ""
+
 #: src/views/certificate/DNSCredential.vue:96
 msgid "We will add one or more TXT records to the DNS records of your domain for ownership verification."
 msgstr ""

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 255 - 174
app/src/language/pt_PT/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 267 - 167
app/src/language/ru_RU/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 263 - 170
app/src/language/tr_TR/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 276 - 176
app/src/language/uk_UA/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 277 - 179
app/src/language/vi_VN/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 243 - 213
app/src/language/zh_CN/app.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 244 - 211
app/src/language/zh_TW/app.po


+ 0 - 1
app/src/views/certificate/ACMEUser.vue

@@ -103,7 +103,6 @@ const columns: StdTableColumn[] = [
       hint: $gettext('External Account Binding HMAC Key (optional). Should be in Base64 URL encoding format.'),
       input: {
         placeholder: $gettext('Leave blank if not required by your ACME provider'),
-        type: 'password',
       },
     },
     hiddenInDetail: true,

+ 11 - 1
app/src/views/site/site_edit/components/Cert/ObtainCert.vue

@@ -16,7 +16,7 @@ const props = defineProps<{
 }>()
 
 const editorStore = useSiteEditorStore()
-const { ngxConfig, issuingCert, curServerDirectives, curDirectivesMap } = storeToRefs(editorStore)
+const { ngxConfig, issuingCert, curServerDirectives, curDirectivesMap, isDefaultServer, hasWildcardServerName, hasExplicitIpAddress, isIpCertificate, needsManualIpInput } = storeToRefs(editorStore)
 
 const autoCert = defineModel<boolean>('autoCert')
 
@@ -43,6 +43,7 @@ const name = computed(() => {
 })
 
 const refObtainCertLive = useTemplateRef('refObtainCertLive')
+const refAutoCertForm = useTemplateRef('refAutoCertForm')
 
 function issueCert() {
   refObtainCertLive.value?.issue_cert(
@@ -172,6 +173,9 @@ const canNext = computed(() => {
 })
 
 function next() {
+  // Apply manual IP address to domains before proceeding
+  refAutoCertForm.value?.applyManualIpToDomains()
+
   step.value++
   onchange(true)
 }
@@ -191,8 +195,14 @@ function next() {
     >
       <template v-if="step === 1">
         <AutoCertStepOne
+          ref="refAutoCertForm"
           v-model:options="data"
           :no-server-name="noServerName"
+          :is-default-server="isDefaultServer"
+          :has-wildcard-server-name="hasWildcardServerName"
+          :has-explicit-ip-address="hasExplicitIpAddress"
+          :is-ip-certificate="isIpCertificate"
+          :needs-manual-ip-input="needsManualIpInput"
         />
       </template>
       <template v-else-if="step === 2">

+ 52 - 0
app/src/views/site/site_edit/components/SiteEditor/store.ts

@@ -154,6 +154,53 @@ export const useSiteEditorStore = defineStore('siteEditor', () => {
     return false
   })
 
+  const isDefaultServer = computed(() => {
+    if (curDirectivesMap.value.listen) {
+      for (const v of curDirectivesMap.value.listen) {
+        const params = v?.params || ''
+        if (params.includes('443') && params.includes('ssl') && params.includes('default_server'))
+          return true
+      }
+    }
+
+    return false
+  })
+
+  const hasWildcardServerName = computed(() => {
+    if (curDirectivesMap.value.server_name) {
+      for (const v of curDirectivesMap.value.server_name) {
+        const params = v?.params || ''
+        if (params.includes('_'))
+          return true
+      }
+    }
+
+    return false
+  })
+
+  const hasExplicitIpAddress = computed(() => {
+    if (curDirectivesMap.value.server_name) {
+      for (const v of curDirectivesMap.value.server_name) {
+        const params = v?.params || ''
+        // Check for IPv4 or IPv6 addresses
+        const ipv4Regex = /\b(?:\d{1,3}\.){3}\d{1,3}\b/
+        const ipv6Regex = /\[?(?:[\da-f]{0,4}:){1,7}[\da-f]{0,4}\]?/i
+        if (ipv4Regex.test(params) || ipv6Regex.test(params))
+          return true
+      }
+    }
+
+    return false
+  })
+
+  const isIpCertificate = computed(() => {
+    return isDefaultServer.value || hasWildcardServerName.value
+  })
+
+  const needsManualIpInput = computed(() => {
+    return isIpCertificate.value && !hasExplicitIpAddress.value
+  })
+
   return {
     name,
     advanceMode,
@@ -174,6 +221,11 @@ export const useSiteEditorStore = defineStore('siteEditor', () => {
     configText,
     issuingCert,
     curSupportSSL,
+    isDefaultServer,
+    hasWildcardServerName,
+    hasExplicitIpAddress,
+    isIpCertificate,
+    needsManualIpInput,
     hasServers,
     init,
     save,

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio