瀏覽代碼

fix: site add issues

0xJacky 2 年之前
父節點
當前提交
6b640381e8

+ 1 - 1
frontend/docs/.vitepress/config.ts

@@ -29,7 +29,7 @@ export default defineConfig({
         nav: [
             {text: 'Home', link: '/'},
             {text: 'Guide', link: '/guide/about'},
-            {text: 'Demo', link: 'https://nginxui.jackyu.cn'}
+            {text: 'Demo', link: 'https://demo.nginxui.com'}
         ],
 
         sidebar: sidebar(),

+ 1 - 1
frontend/docs/guide/about.md

@@ -38,7 +38,7 @@ managing your Nginx server.
 
 ## Demo
 
-URL:[https://nginxui.jackyu.cn](https://nginxui.jackyu.cn)
+URL:[https://demo.nginxui.com](https://demo.nginxui.com)
 
 - Username:admin
 - Password:admin

+ 1 - 1
frontend/docs/zh_CN/guide/about.md

@@ -36,7 +36,7 @@ Nginx UI 是一个全新的 Nginx 网络管理界面,旨在简化 Nginx 服务
 
 ## 在线预览
 
-网址:[https://nginxui.jackyu.cn](https://nginxui.jackyu.cn)
+网址:[https://demo.nginxui.com](https://demo.nginxui.com)
 
 - 用户名:admin
 - 密码:admin

+ 10 - 4
frontend/src/views/domain/DomainAdd.vue

@@ -5,7 +5,7 @@ import NgxConfigEditor from '@/views/domain/ngx_conf/NgxConfigEditor.vue'
 import {useGettext} from 'vue3-gettext'
 import domain from '@/api/domain'
 import ngx from '@/api/ngx'
-import {computed, reactive, ref} from 'vue'
+import {computed, provide, reactive, ref} from 'vue'
 import {message} from 'ant-design-vue'
 import {useRouter} from 'vue-router'
 
@@ -38,13 +38,12 @@ function init() {
 }
 
 function save() {
-    ngx.build_config(ngx_config).then(r => {
+    return ngx.build_config(ngx_config).then(r => {
         domain.save(ngx_config.name, {name: ngx_config.name, content: r.content, overwrite: true}).then(() => {
             message.success($gettext('Saved successfully'))
 
             domain.enable(ngx_config.name).then(() => {
                 message.success($gettext('Enabled successfully'))
-                current_step.value++
                 window.scroll({top: 0, left: 0, behavior: 'smooth'})
             }).catch(r => {
                 message.error(r.message ?? $gettext('Enable failed'), 5)
@@ -79,6 +78,13 @@ const has_server_name = computed(() => {
 
     return false
 })
+
+provide('save_site_config', save)
+
+async function next() {
+    await save()
+    current_step.value++
+}
 </script>
 
 <template>
@@ -129,7 +135,7 @@ const has_server_name = computed(() => {
             <a-space v-if="current_step<2">
                 <a-button
                     type="primary"
-                    @click="save"
+                    @click="next"
                     :disabled="!ngx_config.name||!has_server_name"
                 >
                     <translate>Next</translate>

+ 1 - 1
frontend/src/views/domain/cert/IssueCert.vue

@@ -48,7 +48,7 @@ async function onchange() {
 </script>
 
 <template>
-    <obtain-cert ref="obtain_cert" :key="update"/>
+    <obtain-cert ref="obtain_cert" :key="update" @update:auto_cert="r=>enabled=r"/>
     <div class="issue-cert">
         <a-form-item :label="$gettext('Encrypt website with Let\'s Encrypt')">
             <a-switch

+ 3 - 3
frontend/src/views/domain/cert/components/AutoCertStepOne.vue

@@ -1,11 +1,11 @@
 <script setup lang="ts">
-import {inject, Ref} from 'vue'
+import {inject} from 'vue'
 import {useGettext} from 'vue3-gettext'
 import DNSChallenge from '@/views/domain/cert/components/DNSChallenge.vue'
 
 const {$gettext} = useGettext()
-const no_server_name: Ref = inject('no_server_name')!
-const data: Ref = inject('data')!
+const no_server_name = inject('no_server_name')
+const data = inject('data')
 </script>
 
 <template>

+ 14 - 9
frontend/src/views/domain/cert/components/ObtainCert.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import {useGettext} from 'vue3-gettext'
-import {computed, inject, nextTick, provide, reactive, Ref, ref} from 'vue'
+import {computed, inject, nextTick, provide, reactive, ref} from 'vue'
 import websocket from '@/lib/websocket'
 import Modal from 'ant-design-vue/lib/modal'
 import {message} from 'ant-design-vue'
@@ -10,6 +10,8 @@ import AutoCertStepOne from '@/views/domain/cert/components/AutoCertStepOne.vue'
 
 const {$gettext, interpolate} = useGettext()
 
+const emit = defineEmits(['update:auto_cert'])
+
 const modalVisible = ref(false)
 
 const step = ref(1)
@@ -34,10 +36,10 @@ provide('data', data)
 
 const logContainer = ref(null)
 
-const save_site_config: Function = inject('save_site_config')!
-const no_server_name: Ref = inject('no_server_name')!
+const save_site_config = inject('save_site_config')!
+const no_server_name = inject('no_server_name')!
 const props: any = inject('props')!
-const issuing_cert: Ref<boolean> = inject('issuing_cert')!
+const issuing_cert = inject('issuing_cert')!
 
 async function callback(ssl_certificate: string, ssl_certificate_key: string) {
     props.directivesMap['ssl_certificate'][0]['params'] = ssl_certificate
@@ -69,12 +71,13 @@ async function onchange(r: boolean) {
 
                 v.locations.push(...r.locations)
             })
+        }).then(async () => {
+            // if ssl_certificate is empty, do not save, just use the config from last step.
+            if (props.directivesMap['ssl_certificate']?.[0]) {
+                await save_site_config()
+            }
+            job()
         })
-        // if ssl_certificate is empty, do not save, just use the config from last step.
-        if (!props.directivesMap['ssl_certificate']?.[0]) {
-            await save_site_config()
-        }
-        job()
     } else {
         await props.ngx_config.servers.forEach((v: any) => {
             v.locations = v.locations.filter((l: any) => l.path !== '/.well-known/acme-challenge')
@@ -82,6 +85,8 @@ async function onchange(r: boolean) {
         save_site_config()
         change_auto_cert(r)
     }
+
+    emit('update:auto_cert', r)
 }
 
 function job() {

+ 6 - 2
frontend/src/views/domain/ngx_conf/NgxConfigEditor.vue

@@ -36,9 +36,13 @@ function confirm_change_tls(r: boolean) {
         okText: $gettext('OK'),
         cancelText: $gettext('Cancel'),
         async onOk() {
-            await template.get_block('letsencrypt.conf').then(r => {
+            await template.get_block('letsencrypt.conf').then(async r => {
                 const first = props.ngx_config.servers[0]
-                first.locations = first.locations.filter((l: any) => l.path !== '/.well-known/acme-challenge')
+                if (!first.locations) {
+                    first.locations = []
+                } else {
+                    first.locations = first.locations.filter((l: any) => l.path !== '/.well-known/acme-challenge')
+                }
                 first.locations.push(...r.locations)
             })
             await save_site_config()

+ 24 - 0
resources/development/nginx/sites-available/test.nginxui.com

@@ -0,0 +1,24 @@
+server {
+    listen 80;
+    listen [::]:80;
+    server_name test.nginxui.com;
+    location /.well-known/acme-challenge {
+        proxy_set_header Host $host;
+        proxy_set_header X-Real_IP $remote_addr;
+        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
+        proxy_pass http://127.0.0.1:5002;
+    }
+}
+server {
+    listen 443 ssl http2;
+    listen [::]:443 ssl http2;
+    server_name test.nginxui.com;
+    ssl_certificate /etc/nginx/ssl/test.nginxui.com/fullchain.cer;
+    ssl_certificate_key /etc/nginx/ssl/test.nginxui.com/private.key;
+    location /.well-known/acme-challenge {
+        proxy_set_header Host $host;
+        proxy_set_header X-Real_IP $remote_addr;
+        proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
+        proxy_pass http://127.0.0.1:5002;
+    }
+}

+ 1 - 0
resources/development/nginx/sites-enabled/test.nginxui.com

@@ -0,0 +1 @@
+/etc/nginx/sites-available/test.nginxui.com

+ 64 - 0
resources/development/nginx/ssl/test.nginxui.com/fullchain.cer

@@ -0,0 +1,64 @@
+-----BEGIN CERTIFICATE-----
+MIIFfzCCBGegAwIBAgITAP9GkfaxXhFDoVXgtmZotSiy7jANBgkqhkiG9w0BAQsF
+ADBDMQswCQYDVQQGEwJVUzESMBAGA1UEChMJZ29vZCBndXlzMSAwHgYDVQQDExdD
+QSBpbnRlcm1lZGlhdGUgKFJTQSkgQTAeFw0yMzA1MDEwNDM4MjZaFw0yMzA3MzAw
+NDM4MjVaMBsxGTAXBgNVBAMTEHRlc3Qubmdpbnh1aS5jb20wggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQC6XkUvvse9vHgBhMkmkAsghm+vBUgz+NobetSq
+eIunjLOZ2/Wy43/eY4q1XM6cU49JJ3u09FNQkZ7uKnLR0SdD9mrj6rYkHif/XhRM
+XGtpzua5cW1Hn6THfDeKDEX32z3qanlA2JgRbKgkanTYXsX4iEs+JIeKEtnZkLJV
+pzmcPNPgM9V9i9h13tfTVvI+UTLHgKqCILirHZ9dkJMnkqrO9vBF+JaKKkrtMHmy
+7lr3Q6rJaFJUIjRGWd3tfpuNsxJyEqgkCxin7zhsb5Gh0C+4rUERFhIm3GrxmZjy
+Xg1z3WmdWs4tQTdVjXnNmgRLQC8li8/MUfw6ZxPI6luSx45XAgMBAAGjggKSMIIC
+jjAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
+MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLNVFxcj8mg1/qMfWmLhwIIJXB1vMCsG
+A1UdIwQkMCKAIGI1hqilwtQoFMkbW0tW2caTKmjXSp6GN958mmXVREPyMHEGCCsG
+AQUFBwEBBGUwYzAiBggrBgEFBQcwAYYWaHR0cDovLzEyNy4wLjAuMTo0MDAyLzA9
+BggrBgEFBQcwAoYxaHR0cDovLzEyNy4wLjAuMTo0MDAxL2FpYS9pc3N1ZXIvNjYw
+NTQ0MDQ5ODM2OTc0MTAbBgNVHREEFDASghB0ZXN0Lm5naW54dWkuY29tMCcGA1Ud
+HwQgMB4wHKAaoBiGFmh0dHA6Ly9leGFtcGxlLmNvbS9jcmwwQAYDVR0gBDkwNzAI
+BgZngQwBAgEwKwYDKgMEMCQwIgYIKwYBBQUHAgEWFmh0dHA6Ly9leGFtcGxlLmNv
+bS9jcHMwggEGBgorBgEEAdZ5AgQCBIH3BIH0APIAdwBS1OjKcYTIySRcMxB6LwuX
+nigzBYcjQiJ4MQqzXb9N3gAAAYfV0cJhAAAEAwBIMEYCIQD3cUf9kNmiF82CBBXs
+3aLeEzmGADm7ZHDbbX+RMd05pQIhAJf54zQOK9XXzE9YiVCgFq9StTIAkumnxYHI
+g2qxMxBaAHcAHRrTQca8iy14Qbrw6/itgVzVWTcaENF3tWnJP743pq8AAAGH1dHC
+YQAABAMASDBGAiEA0KLd3MS6zJJq44lkNHBcJumvTga70oECAa18e5P2c8sCIQCV
+VSryWzSf8l/tw1yt/IHWuNvKw1YA6ASJw+l+fa1JRzANBgkqhkiG9w0BAQsFAAOC
+AQEAW66Qo7rE6oDectPJC9WtARsmMu1UzUUyfm/xHP/jNtZXxHrPvxKJvR93wm5i
+Vf1WrhegQv1NigtykqKIpB3mxXzW1YkBKCesv7LapH5gNux+Zmy9QTWgHw4wOs5b
+DgNz8puAebg3Ww86czsEJJxldwoOyYyFMeVMZrzOAHWsD51UU9N8tta8eoEvVM8E
+Hrln1TAID6fcKkUKEhd86sjxG6tTKOjaPZfkBK7v0P4MvfkLhtVs2gmNt7F2tlLr
+WEQG3c6ElcPnEopKZ7iXXdapNNVCl6YP0JOBQ1IHg+sbXATZSzWdA6KEj9fD7tX+
+4JGNOuTSCvTLLWKwMvafQxfcfw==
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIFZzCCA0+gAwIBAgIQHPTBy0utaJ82mHJs9V3u8zANBgkqhkiG9w0BAQsFADA5
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJZ29vZCBndXlzMRYwFAYDVQQDEw1DQSBy
+b290IChSU0EpMB4XDTIwMDEwMTEyMDAwMFoXDTQwMDEwMTEyMDAwMFowQzELMAkG
+A1UEBhMCVVMxEjAQBgNVBAoTCWdvb2QgZ3V5czEgMB4GA1UEAxMXQ0EgaW50ZXJt
+ZWRpYXRlIChSU0EpIEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCk
+f1rlGJeno27J8UAltWo8PopRsTP93Il6+L+SScaOUQsM+TCbTO5EJ4xC+d3Unp8v
+iZRLAB1/lGhHh/Uifzov2ux2sa9J4kxlfCxVaaCx6maOs9KnfGUug2hcUCh1oUVv
+zD9X9VkWdBdR+kKJvYqWJlU/EJxEa5ERjFp591LQBpR7ksZrsbLvXeywqVS3ek8s
+d7w+ZqpYOfo6DNLl5aEJlk6F6CiSjmT352n8dnsOEIEL+bOusLhP5F8pED85geU5
+rijc38fZ+gfZAVVenz7kqBh7ld6qT5inIM4uQa7oCuFX2dZ0jqm5TFBBtQp9dkFv
+WFz9kEb/CVJr1IsTdp1PAgMBAAGjggFfMIIBWzAOBgNVHQ8BAf8EBAMCAYYwHQYD
+VR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYBAf8CAQAw
+KQYDVR0OBCIEIGI1hqilwtQoFMkbW0tW2caTKmjXSp6GN958mmXVREPyMCsGA1Ud
+IwQkMCKAINmvCHaWHo5MD5lKL52otAsr/TsCX5Hwfy5euQ6zIAWEMFgGCCsGAQUF
+BwEBBEwwSjAjBggrBgEFBQcwAYYXaHR0cDovL2V4YW1wbGUuY29tL29jc3AwIwYI
+KwYBBQUHMAKGF2h0dHA6Ly9leGFtcGxlLmNvbS9yb290MCcGA1UdHwQgMB4wHKAa
+oBiGFmh0dHA6Ly9leGFtcGxlLmNvbS9jcmwwOwYDVR0gBDQwMjAEBgIqAzAqBgIt
+BjAkMCIGCCsGAQUFBwIBFhZodHRwOi8vZXhhbXBsZS5jb20vY3BzMA0GCSqGSIb3
+DQEBCwUAA4ICAQCTLNQlCzHynESAvtPRV1FPaOQhx01RofwS/0Zg3IH5oXxSC98C
+n2L0xHN1gCaJai9XutrFtMCjeBmese48QoPa8MxrB1UpmZ1AuFOQAfHWJZbYPp0V
+PxgY34W9Onb+JPnKTbL9ofKUV0aX67eJ5KKFD1G2z+y9Lz1oA3yJpGzqOY/JCWYz
+q46ik0bmgcGfol6F/T5hoE8pZk8Wr+nNUpSuOSNp7c/g2/pKDRWK8trTrG3owtaJ
+LbQc+W4e97AtTg6DGvR5gftar/+4g2o0xhKSnep+s/bf5NFXVDCTvCmemrbR8Hr7
+NLDKXWuGMoMKIxhyPX6ttpU2Um3rQ1rCQbJ5yWIREZvbdaeK8HSRE3GYE71Z3n/0
+0Kmtg2BKGkrJzcqUSG4o+9mdSjhJ65J76ri5tVQby7Ai7W2KlNjpdI6GYtejUAlf
+vZz5N0e2X36XLPZ8tz04Ix9KLHXMEuA7w/aOglH1Lei+PPp7kBjvXAL66soqCTqu
+49yNbPPGIjGO453+jNzxhbeimh6a5/Fwd4SjsdSBe8AwIGGZTzLiIzCNM5OmcoUf
+Tl5RrVXau4DvX5KvfwOLusl/uJH+7oETJlbi8+fNn2ioYfHg5/Tu3zKZw/Y+6wSA
+LsOIJrFmJEgIBUnWp/B1ZC6TeIokmw5FeJsY1UnFDWsPVcax2T/tg6BZ5Q==
+-----END CERTIFICATE-----

+ 27 - 0
resources/development/nginx/ssl/test.nginxui.com/private.key

@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAul5FL77Hvbx4AYTJJpALIIZvrwVIM/jaG3rUqniLp4yzmdv1
+suN/3mOKtVzOnFOPSSd7tPRTUJGe7ipy0dEnQ/Zq4+q2JB4n/14UTFxrac7muXFt
+R5+kx3w3igxF99s96mp5QNiYEWyoJGp02F7F+IhLPiSHihLZ2ZCyVac5nDzT4DPV
+fYvYdd7X01byPlEyx4CqgiC4qx2fXZCTJ5KqzvbwRfiWiipK7TB5su5a90OqyWhS
+VCI0Rlnd7X6bjbMSchKoJAsYp+84bG+RodAvuK1BERYSJtxq8ZmY8l4Nc91pnVrO
+LUE3VY15zZoES0AvJYvPzFH8OmcTyOpbkseOVwIDAQABAoIBAEXw6QAhFe7j0xmm
+zqKVPkfHjBRf5Bf1FU1ozHTpZmfLyv876DppXGyGaODlYniSd1yZ37gqVTYQYFe7
+QHnzh0vfJ4A/bnmhg5s3oGCD8p+z0SzZH4zYoctnl6RMNNnuwo69xKGMZ41qfLOl
+7BHjh2JdK/e3V9J+fplCz1qLtngmS9XwE04xKkz1TKARkFaaGvb2tFGaa4xLOViu
+LXW+Jw93o5bD9+7CnFL+GGXXvm24XogMS/PrzlJW2fnct4U0pwVKeWhDYI5SCbgu
+RzbSKA4CfhN6NewgGt0FSkcfqGBVNP7+bZurqAq5jNcKi0diECVFf/jg+3riTioS
+IdtHjFkCgYEA1ebS1F9NwCDAZN5MEB8vpJEkYbzf1p7ieIVM2Jplc/YpOkONcRmY
+bA0CVa8nimxvkOVs4i216Ek1azTk+v/QYNW92IQH2Pg4fPJUHvlCs792KSyK0mPj
+CtPNjuGsbTen+rX94C4/+AFN7wFuWdQV0enf+/mmXZfphDSxTL6eRbUCgYEA3ww1
+g75X0e1kC6CDG+iV1bAHwL9avzE5xWki/f1gCqU7YtHN8rCrvDLErS4guLD6bE05
+u9GIaHHKO7w/Dsrw0OD16IvH0+3Y2fN+GL9qozOsuwxVRrYJMlkv4C020d++LaEU
+YBV+wewNQJPzGiPsmAx4x/FYVikwzqQSdqkuC1sCgYAeYGBSbpJhFYWdDYCpzXP7
+n+0VwDfdh8TLrsqB/DMqK6whLRS6GhNuTM6nEm/AFbQmVJ6I5ErwCO2AIwvdpVSX
+W+NRCzb+FgoXnGZb27QgSLFkGYJBbJQCpp+Lifrtq7i8PvolywukkbLanU5pjVfn
+7pmzc/mvUvKDpuQC7RMW/QKBgQCYsyAT8ITo+E+M0jfQLHwfziKQp7B1wjqd1uuY
+3RUaVKKCdcY8Bw2bi1owgarvJmJbMMd8uOddMcHVAXxeITualNhlewS0J1pVZCiI
+wss7rc3sRHZBMbC8ImjvXaTxK+9kB6oOWcjs9DDibCd7VurL8YXixGzIl+yNG7B0
+QkB+jwKBgH2VeXcWWZYdMJ8DuwZIv9qIXiHR78lo0+2grgQCxcZ2VWoW2kMsXUUp
+sJ/xYVZ25E97zyW+TkoCTEGl6PN7WLgNO42HlasdFRIM4i8+zu+zleOLdkpVtkhU
+voMnWMqDWRncgwBsap8scdDDt1mSOnr72kyVEpm/qv6tELoKLZXI
+-----END RSA PRIVATE KEY-----