From e4f219a2861e3f7a98c1022b6ac275d2b4ca3c27 Mon Sep 17 00:00:00 2001
From: MattIPv4 <me@mattcowley.co.uk>
Date: Thu, 11 Jun 2020 15:03:52 +0100
Subject: [PATCH] Don't use duplicated computed value for nginx dir, watch
 initial value

---
 src/nginxconfig/templates/app.vue             |  5 +----
 .../templates/domain_sections/https.vue       | 21 +++++++------------
 .../templates/global_sections/nginx.vue       | 11 ++++++++++
 src/nginxconfig/templates/setup.vue           |  5 +----
 .../templates/setup_sections/certbot.vue      |  8 +++----
 .../templates/setup_sections/download.vue     |  6 ++++--
 .../templates/setup_sections/ssl.vue          |  7 ++-----
 7 files changed, 30 insertions(+), 33 deletions(-)

diff --git a/src/nginxconfig/templates/app.vue b/src/nginxconfig/templates/app.vue
index 6acdb71..1504301 100644
--- a/src/nginxconfig/templates/app.vue
+++ b/src/nginxconfig/templates/app.vue
@@ -139,9 +139,6 @@ THE SOFTWARE.
             activeDomains() {
                 return this.$data.domains.map((domain, index) => [domain, index]).filter(d => d[0] !== null);
             },
-            nginxDir() {
-                return this.$data.global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '');
-            },
             confFiles() {
                 return generators(this.$data.domains.filter(d => d !== null), this.$data.global);
             },
@@ -217,7 +214,7 @@ THE SOFTWARE.
             updateDiff(newConf, oldConf) {
                 // Calculate the diff & highlight after render
                 this.$data.confFilesOutput = Object.values(diff(newConf, oldConf)).map(conf => {
-                    const name = `${escape(this.nginxDir)}/${conf[0]}`;
+                    const name = `${escape(this.$data.global.nginx.nginxConfigDirectory.computed)}/${conf[0]}`;
                     return [
                         name,
                         conf[1],
diff --git a/src/nginxconfig/templates/domain_sections/https.vue b/src/nginxconfig/templates/domain_sections/https.vue
index 7156ae0..e613f1a 100644
--- a/src/nginxconfig/templates/domain_sections/https.vue
+++ b/src/nginxconfig/templates/domain_sections/https.vue
@@ -165,7 +165,7 @@ THE SOFTWARE.
                         <input v-model="sslCertificate"
                                class="input"
                                type="text"
-                               :placeholder="`${nginxDir}/ssl/${$parent.$props.data.server.domain.computed}.crt`"
+                               :placeholder="`${$parent.$parent.$data.global.nginx.nginxConfigDirectory.computed}/ssl/${$parent.$props.data.server.domain.computed}.crt`"
                         />
                     </div>
                 </div>
@@ -182,7 +182,7 @@ THE SOFTWARE.
                         <input v-model="sslCertificateKey"
                                class="input"
                                type="text"
-                               :placeholder="`${nginxDir}/ssl/${$parent.$props.data.server.domain.computed}.key`"
+                               :placeholder="`${$parent.$parent.$data.global.nginx.nginxConfigDirectory.computed}/ssl/${$parent.$props.data.server.domain.computed}.key`"
                         />
                     </div>
                 </div>
@@ -247,28 +247,23 @@ THE SOFTWARE.
     };
 
     export default {
-        name: 'DomainHTTPS',                            // Component name
-        display: i18n.common.https,                     // Display name for tab
-        key: 'https',                                   // Key for data in parent
-        delegated: delegatedFromDefaults(defaults),     // Data the parent will present here
+        name: 'DomainHTTPS',                                // Component name
+        display: i18n.common.https,                         // Display name for tab
+        key: 'https',                                       // Key for data in parent
+        delegated: delegatedFromDefaults(defaults),         // Data the parent will present here
         components: {
             PrettyCheck,
             PrettyRadio,
         },
         props: {
-            data: Object,                               // Data delegated back to us from parent
+            data: Object,                                   // Data delegated back to us from parent
         },
         data () {
             return {
                 i18n,
             };
         },
-        computed: {
-            ...computedFromDefaults(defaults, 'https'), // Getters & setters for the delegated data
-            nginxDir() {
-                return this.$parent.$parent.$data.global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '');
-            },
-        },
+        computed: computedFromDefaults(defaults, 'https'),  // Getters & setters for the delegated data
         watch: {
             // Disable everything if https is disabled
             '$props.data.https': {
diff --git a/src/nginxconfig/templates/global_sections/nginx.vue b/src/nginxconfig/templates/global_sections/nginx.vue
index c33208e..a71ae2a 100644
--- a/src/nginxconfig/templates/global_sections/nginx.vue
+++ b/src/nginxconfig/templates/global_sections/nginx.vue
@@ -128,6 +128,7 @@ THE SOFTWARE.
     const defaults = {
         nginxConfigDirectory: {
             default: '/etc/nginx/',
+            computed: '/etc/nginx', // We use a watcher to trim trailing slashes
             enabled: true,
         },
         workerProcesses: {
@@ -170,6 +171,16 @@ THE SOFTWARE.
         },
         computed: computedFromDefaults(defaults, 'nginx'),  // Getters & setters for the delegated data
         watch: {
+            // Clean nginx directory of trailing slashes
+            '$props.data.nginxConfigDirectory': {
+                handler(data) {
+                    // This might cause recursion, but seems not to
+                    if (data.enabled)
+                        if (data.computed.endsWith('/'))
+                            data.computed = data.computed.replace(/\/+$/, '');
+                },
+                deep: true,
+            },
             // Check worker processes selection is valid
             '$props.data.workerProcesses': {
                 handler(data) {
diff --git a/src/nginxconfig/templates/setup.vue b/src/nginxconfig/templates/setup.vue
index 9b5ecd0..54dc5af 100644
--- a/src/nginxconfig/templates/setup.vue
+++ b/src/nginxconfig/templates/setup.vue
@@ -94,9 +94,6 @@ THE SOFTWARE.
                 if (index >= 0) return tabs[index];
                 return false;
             },
-            nginxDir() {
-                return this.$props.data.global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '');
-            },
             tarName() {
                 const domains = this.$props.data.domains.filter(d => d !== null).map(d => d.server.domain.computed);
                 return `nginxconfig.io-${domains.join(',')}.tar.gz`;
@@ -149,7 +146,7 @@ THE SOFTWARE.
 
                 // Convert it to base64 string
                 const b64 = btoa(String.fromCharCode(...contents));
-                return `echo '${b64}' | base64 --decode > ${this.nginxDir}/${this.tarName}`;
+                return `echo '${b64}' | base64 --decode > ${this.$props.data.global.nginx.nginxConfigDirectory.computed}/${this.tarName}`;
             },
             setupCopy() {
                 const originalText = this.$refs.copyTar.textContent;
diff --git a/src/nginxconfig/templates/setup_sections/certbot.vue b/src/nginxconfig/templates/setup_sections/certbot.vue
index 811f58d..8b787eb 100644
--- a/src/nginxconfig/templates/setup_sections/certbot.vue
+++ b/src/nginxconfig/templates/setup_sections/certbot.vue
@@ -113,9 +113,6 @@ THE SOFTWARE.
             };
         },
         computed: {
-            nginxDir() {
-                return this.$props.data.global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '');
-            },
             letsEncryptDir() {
                 return this.$props.data.global.https.letsEncryptRoot.computed.replace(/\/+$/, '');
             },
@@ -128,12 +125,13 @@ THE SOFTWARE.
                 return false;
             },
             sitesAvailable() {
-                if (!this.$props.data.global.tools.modularizedStructure.computed) return `${this.nginxDir}/nginx.conf`;
+                if (!this.$props.data.global.tools.modularizedStructure.computed)
+                    return `${this.$props.data.global.nginx.nginxConfigDirectory.computed}/nginx.conf`;
 
                 const enabledAvailable = this.$props.data.global.tools.symlinkVhost.computed ? 'available' : 'enabled';
                 return this.$props.data.domains
                     .filter(domain => domain.https.certType.computed === 'letsEncrypt')
-                    .map(domain => `${this.nginxDir}/sites-${enabledAvailable}/${domain.server.domain.computed}.conf`)
+                    .map(domain => `${this.$props.data.global.nginx.nginxConfigDirectory.computed}/sites-${enabledAvailable}/${domain.server.domain.computed}.conf`)
                     .join(' ');
             },
             certbotCmds() {
diff --git a/src/nginxconfig/templates/setup_sections/download.vue b/src/nginxconfig/templates/setup_sections/download.vue
index 5e606ab..233f8ee 100644
--- a/src/nginxconfig/templates/setup_sections/download.vue
+++ b/src/nginxconfig/templates/setup_sections/download.vue
@@ -33,7 +33,7 @@ THE SOFTWARE.
                     <b>&nbsp;<a @click="$parent.downloadTar">{{ $parent.tarName }}</a></b>
                     <br />
                     <span v-html="i18n.templates.setupSections.download.andUploadItToYourServers"></span>
-                    <code class="slim">{{ $parent.nginxDir }}</code>
+                    <code class="slim">{{ $props.data.global.nginx.nginxConfigDirectory.computed }}</code>
                     {{ i18n.templates.setupSections.download.directory }}
                 </p>
                 <p>
@@ -50,7 +50,9 @@ THE SOFTWARE.
                 <p>
                     <span v-html="i18n.templates.setupSections.download.navigateToYourNginxConfigurationDirectoryOnYourServer"></span>
                     <br />
-                    <BashPrism :key="$parent.nginxDir" :cmd="`cd ${$parent.nginxDir}`"></BashPrism>
+                    <BashPrism :key="$props.data.global.nginx.nginxConfigDirectory.computed"
+                               :cmd="`cd ${$props.data.global.nginx.nginxConfigDirectory.computed}`"
+                    ></BashPrism>
                 </p>
             </li>
 
diff --git a/src/nginxconfig/templates/setup_sections/ssl.vue b/src/nginxconfig/templates/setup_sections/ssl.vue
index 2156dcf..4948759 100644
--- a/src/nginxconfig/templates/setup_sections/ssl.vue
+++ b/src/nginxconfig/templates/setup_sections/ssl.vue
@@ -31,8 +31,8 @@ THE SOFTWARE.
                 <p>
                     <span v-html="i18n.templates.setupSections.ssl.generateDiffieHellmanKeysByRunningThisCommandOnYourServer"></span>
                     <br />
-                    <BashPrism :key="`${nginxDir}-${diffieHellmanValue}`"
-                               :cmd="`openssl dhparam -out ${nginxDir}/dhparam.pem ${diffieHellmanValue}`"
+                    <BashPrism :key="`${$props.data.global.nginx.nginxConfigDirectory.computed}-${diffieHellmanValue}`"
+                               :cmd="`openssl dhparam -out ${$props.data.global.nginx.nginxConfigDirectory.computed}/dhparam.pem ${diffieHellmanValue}`"
                     ></BashPrism>
                 </p>
             </li>
@@ -83,9 +83,6 @@ THE SOFTWARE.
             };
         },
         computed: {
-            nginxDir() {
-                return this.$props.data.global.nginx.nginxConfigDirectory.computed.replace(/\/+$/, '');
-            },
             letsEncryptDir() {
                 return this.$props.data.global.https.letsEncryptRoot.computed.replace(/\/+$/, '');
             },