Change hash + clipboard implementations

This commit is contained in:
MattIPv4 2020-06-05 17:04:00 +01:00
parent 4b2a476227
commit 5a934a37c5
4 changed files with 53 additions and 42 deletions

35
package-lock.json generated
View file

@ -3077,7 +3077,6 @@
"version": "2.0.6", "version": "2.0.6",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz",
"integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==",
"optional": true,
"requires": { "requires": {
"good-listener": "^1.2.2", "good-listener": "^1.2.2",
"select": "^1.1.2", "select": "^1.1.2",
@ -3406,14 +3405,6 @@
"resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
}, },
"copy-to-clipboard": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz",
"integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==",
"requires": {
"toggle-selection": "^1.0.6"
}
},
"copy-webpack-plugin": { "copy-webpack-plugin": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz",
@ -4319,8 +4310,7 @@
"delegate": { "delegate": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
"optional": true
}, },
"delegates": { "delegates": {
"version": "1.0.0", "version": "1.0.0",
@ -5998,7 +5988,6 @@
"version": "1.2.2", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"optional": true,
"requires": { "requires": {
"delegate": "^3.1.2" "delegate": "^3.1.2"
} }
@ -10382,9 +10371,9 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
}, },
"sass": { "sass": {
"version": "1.26.7", "version": "1.26.8",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.26.7.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.8.tgz",
"integrity": "sha512-xgNazdkr6yvgHEfNaOjKtZzhDZmKYMCmoRKMPrTDo7YvjaITIzU2DDYsIUuN/atAg7/JOxPeCQHH7TtCo5Tq2g==", "integrity": "sha512-yvtzyrKLGiXQu7H12ekXqsfoGT/aTKeMDyVzCB675k1HYuaj0py63i8Uf4SI9CHXj6apDhpfwbUr3gGOjdpu2Q==",
"requires": { "requires": {
"chokidar": ">=2.0.0 <4.0.0" "chokidar": ">=2.0.0 <4.0.0"
} }
@ -10953,8 +10942,7 @@
"select": { "select": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
"optional": true
}, },
"select-hose": { "select-hose": {
"version": "2.0.0", "version": "2.0.0",
@ -11201,6 +11189,11 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
}, },
"simple-js-sha2-256": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/simple-js-sha2-256/-/simple-js-sha2-256-1.0.7.tgz",
"integrity": "sha512-Z5dUk/kYx3NlkrNTe2tE+a01eVagNmbZ2Sc2wfqCdYjVe6LSs/xZ1UlI0eLKSfMVCjNWz7J+nKwX/7S6JX9aNw=="
},
"simple-swizzle": { "simple-swizzle": {
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@ -12062,8 +12055,7 @@
"tiny-emitter": { "tiny-emitter": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
"optional": true
}, },
"tiny-inflate": { "tiny-inflate": {
"version": "1.0.3", "version": "1.0.3",
@ -12127,11 +12119,6 @@
"repeat-string": "^1.6.1" "repeat-string": "^1.6.1"
} }
}, },
"toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI="
},
"toidentifier": { "toidentifier": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",

View file

@ -38,9 +38,8 @@
}, },
"homepage": "https://github.com/digitalocean/nginxconfig.io#readme", "homepage": "https://github.com/digitalocean/nginxconfig.io#readme",
"dependencies": { "dependencies": {
"clipboard": "^2.0.6",
"clone": "^2.1.2", "clone": "^2.1.2",
"copy-to-clipboard": "^3.3.1",
"create-hash": "^1.2.0",
"deep-equal": "^2.0.3", "deep-equal": "^2.0.3",
"diff": "^4.0.2", "diff": "^4.0.2",
"do-bulma": "git+https://github.com/do-community/do-bulma.git", "do-bulma": "git+https://github.com/do-community/do-bulma.git",
@ -50,6 +49,7 @@
"pretty-checkbox-vue": "^1.1.9", "pretty-checkbox-vue": "^1.1.9",
"prismjs": "^1.20.0", "prismjs": "^1.20.0",
"qs": "^6.9.4", "qs": "^6.9.4",
"simple-js-sha2-256": "^1.0.7",
"tarts": "^1.0.0", "tarts": "^1.0.0",
"vue": "^2.6.11", "vue": "^2.6.11",
"vue-select": "^3.10.3" "vue-select": "^3.10.3"
@ -60,7 +60,7 @@
"duplicate-package-checker-webpack-plugin": "^3.0.0", "duplicate-package-checker-webpack-plugin": "^3.0.0",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"eslint-plugin-vue": "^5.2.3", "eslint-plugin-vue": "^5.2.3",
"sass": "^1.26.7", "sass": "^1.26.8",
"sass-lint": "^1.13.1", "sass-lint": "^1.13.1",
"sass-lint-auto-fix": "^0.21.0", "sass-lint-auto-fix": "^0.21.0",
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",

View file

@ -81,7 +81,7 @@ THE SOFTWARE.
<h2>{{ i18n.templates.app.configFiles }}</h2> <h2>{{ i18n.templates.app.configFiles }}</h2>
<div ref="files" class="columns is-multiline"> <div ref="files" class="columns is-multiline">
<NginxPrism v-for="(confContents, confName) in confFilesOutput" <NginxPrism v-for="(confContents, confName) in confFilesOutput"
:key="`${confName}-${hash(confContents)}`" :key="`${confName}-${sha2_256(confContents)}`"
:name="`${nginxDir}/${confName}`" :name="`${nginxDir}/${confName}`"
:conf="confContents" :conf="confContents"
:half="Object.keys(confFilesOutput).length > 1 && !splitColumn" :half="Object.keys(confFilesOutput).length > 1 && !splitColumn"
@ -100,7 +100,7 @@ THE SOFTWARE.
import { diffLines } from 'diff'; import { diffLines } from 'diff';
import escape from 'escape-html'; import escape from 'escape-html';
import deepEqual from 'deep-equal'; import deepEqual from 'deep-equal';
import createHash from 'create-hash'; import sha2_256 from 'simple-js-sha2-256';
import Header from 'do-vue/src/templates/header'; import Header from 'do-vue/src/templates/header';
import Footer from 'do-vue/src/templates/footer'; import Footer from 'do-vue/src/templates/footer';
import isChanged from '../util/is_changed'; import isChanged from '../util/is_changed';
@ -197,9 +197,6 @@ THE SOFTWARE.
this.$set(this.$data.domains, index, null); this.$set(this.$data.domains, index, null);
if (this.$data.active === index) this.$data.active = this.$data.domains.findIndex(d => d !== null); if (this.$data.active === index) this.$data.active = this.$data.domains.findIndex(d => d !== null);
}, },
hash(content) {
return createHash('sha256').update(content).digest('base64');
},
checkChange(oldConf) { checkChange(oldConf) {
// If nothing has changed for a tick, we can use the config files // If nothing has changed for a tick, we can use the config files
if (deepEqual(oldConf, this.confFiles)) { if (deepEqual(oldConf, this.confFiles)) {
@ -232,7 +229,7 @@ THE SOFTWARE.
// If a file with the same name existed before, diff! // If a file with the same name existed before, diff!
// TODO: Handle diffing across file renames (eg. when a user changes a domain name) // TODO: Handle diffing across file renames (eg. when a user changes a domain name)
const old = oldConf && oldConf[newFileName]; const old = oldConf && oldConf[newFileName];
if (old && this.hash(old) !== this.hash(newFileConf)) { if (old && old !== newFileConf) {
console.info(`Diffing ${newFileName}...`); console.info(`Diffing ${newFileName}...`);
// Get the diff // Get the diff
@ -279,6 +276,7 @@ THE SOFTWARE.
this.$data.confFilesOutput = newFiles; this.$data.confFilesOutput = newFiles;
this.$nextTick(() => this.$data.confWatcherWaiting = false); this.$nextTick(() => this.$data.confWatcherWaiting = false);
}, },
sha2_256,
}, },
}; };
</script> </script>

View file

@ -55,7 +55,7 @@ THE SOFTWARE.
<div class="buttons is-centered"> <div class="buttons is-centered">
<a class="button is-success" @click="downloadTar">{{ i18n.templates.setup.downloadConfig }}</a> <a class="button is-success" @click="downloadTar">{{ i18n.templates.setup.downloadConfig }}</a>
<a class="button is-primary" @click="copyTar">{{ i18n.templates.setup.copyBase64 }}</a> <a ref="copyTar" class="button is-primary">{{ i18n.templates.setup.copyBase64 }}</a>
</div> </div>
</div> </div>
</template> </template>
@ -63,7 +63,7 @@ THE SOFTWARE.
<script> <script>
import tar from 'tarts'; import tar from 'tarts';
import { gzip } from 'pako'; import { gzip } from 'pako';
import copy from 'copy-to-clipboard'; import ClipboardJS from 'clipboard';
import i18n from '../i18n'; import i18n from '../i18n';
import * as Sections from './setup_sections'; import * as Sections from './setup_sections';
@ -102,6 +102,9 @@ THE SOFTWARE.
return `nginxconfig.io-${domains.join(',')}.tar.gz`; return `nginxconfig.io-${domains.join(',')}.tar.gz`;
}, },
}, },
mounted() {
this.setupCopy();
},
methods: { methods: {
tabClass(tab) { tabClass(tab) {
if (tab === this.$data.active) return 'is-active'; if (tab === this.$data.active) return 'is-active';
@ -109,7 +112,7 @@ THE SOFTWARE.
if (tabs.indexOf(tab) < tabs.indexOf(this.$data.active)) return 'is-before'; if (tabs.indexOf(tab) < tabs.indexOf(this.$data.active)) return 'is-before';
return undefined; return undefined;
}, },
async tarContents() { tarContents() {
const data = []; const data = [];
// Add all our config files to the tar // Add all our config files to the tar
@ -129,9 +132,9 @@ THE SOFTWARE.
return gzip(tar(data)); return gzip(tar(data));
}, },
async downloadTar() { downloadTar() {
// Get the config files as a compressed tar // Get the config files as a compressed tar
const contents = await this.tarContents(); const contents = this.tarContents();
// Convert it to a blob and download // Convert it to a blob and download
const blob = new Blob([ contents ], { type: 'application/tar+gzip' }); const blob = new Blob([ contents ], { type: 'application/tar+gzip' });
@ -140,14 +143,37 @@ THE SOFTWARE.
link.download = this.tarName; link.download = this.tarName;
link.click(); link.click();
}, },
async copyTar() { copyTar() {
// Get the config files as a compressed tar // Get the config files as a compressed tar
const contents = await this.tarContents(); const contents = this.tarContents();
// Convert it to base64 string // Convert it to base64 string
const b64 = Buffer.from(contents).toString('base64'); const b64 = Buffer.from(contents).toString('base64');
const command = `echo '${b64}' | base64 --decode > ${this.nginxDir}/${this.tarName}`; return `echo '${b64}' | base64 --decode > ${this.nginxDir}/${this.tarName}`;
copy(command); },
setupCopy() {
const originalText = this.$refs.copyTar.textContent;
const resetText = () => {
setTimeout(() => {
this.$refs.copyTar.textContent = originalText;
}, 5000);
};
const clipboard = new ClipboardJS(this.$refs.copyTar, {
text: this.copyTar,
});
clipboard.on('success', e => {
this.$refs.copyTar.textContent = 'Copied';
e.clearSelection();
resetText();
});
clipboard.on('error', () => {
this.$refs.copyTar.textContent = 'Press Ctrl + C to copy';
resetText();
});
}, },
}, },
}; };