From 0547d2398fa6caa03641472af247bd0e3df55d2b Mon Sep 17 00:00:00 2001 From: ChaotiCryptidz Date: Thu, 13 Jan 2022 18:09:03 +0000 Subject: [PATCH] add hjson support for editing secrets --- package.json | 3 +- src/main.tsx | 1 + .../pages/Secrets/KeyValue/KeyValueEdit.tsx | 94 +++++++++++++------ webpack-dev.config.js | 1 + webpack.config.js | 1 + 5 files changed, 70 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index 879af6c..4e31824 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "devDependencies": { "@babel/core": "^7.16.7", "@babel/eslint-parser": "^7.16.5", + "@babel/plugin-syntax-import-assertions": "^7.16.7", "@babel/plugin-proposal-class-properties": "^7.16.7", "@babel/plugin-proposal-decorators": "^7.16.7", "@babel/plugin-proposal-object-rest-spread": "^7.16.7", @@ -33,12 +34,12 @@ "webpack-dev-server": "^4.7.2" }, "dependencies": { - "@babel/plugin-syntax-import-assertions": "^7.16.7", "clipboard": "^2.0.8", "codejar": "^3.5.0", "core-js": "^3.20.2", "date-fns": "^2.28.0", "file-saver": "^2.0.5", + "hjson": "^3.2.2", "i18next": "^21.6.5", "normalize.css": "^8.0.1", "preact": "^10.6.4", diff --git a/src/main.tsx b/src/main.tsx index 38ba144..57c37f8 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -12,6 +12,7 @@ UIkit.use(Icons); import Prism from "prismjs"; // Don't Sort These! import "prismjs/components/prism-hcl"; +import "prismjs/components/prism-javascript"; import "prismjs/components/prism-json"; Prism.highlightAll(); diff --git a/src/ui/pages/Secrets/KeyValue/KeyValueEdit.tsx b/src/ui/pages/Secrets/KeyValue/KeyValueEdit.tsx index 8696448..5449142 100644 --- a/src/ui/pages/Secrets/KeyValue/KeyValueEdit.tsx +++ b/src/ui/pages/Secrets/KeyValue/KeyValueEdit.tsx @@ -1,10 +1,38 @@ import { CodeEditor } from "../../../elements/CodeEditor"; -import { Component, JSX } from "preact"; +import { Component, createRef, JSX } from "preact"; import { DefaultPageProps } from "../../../../types/DefaultPageProps"; import { SecretTitleElement } from "../SecretTitleElement"; import { setErrorText } from "../../../../pageUtils"; -import { sortedObjectMap, verifyJSONString } from "../../../../utils"; +import { sortedObjectMap } from "../../../../utils"; +import Hjson from "hjson"; import i18next from "i18next"; +import { InputWithTitle } from "../../../elements/InputWithTitle"; + + +function parseJSON(data: string, hJSON = false): Record { + if (hJSON) { + return Hjson.parse(data); + } else { + return JSON.parse(data); + } +} + +function dumpJSON(data: Record, space: number = 0, hJSON = false): string { + if (hJSON) { + return Hjson.stringify(data, null, space); + } else { + return JSON.stringify(data, null, space); + } +} + +export function isValidJSON(str: string, hJSON = false): boolean { + try { + parseJSON(str, hJSON); + } catch (e) { + return false; + } + return true; +} export type KVEditProps = DefaultPageProps & { baseMount: string; @@ -14,19 +42,23 @@ export type KVEditProps = DefaultPageProps & { type KVEditState = | { - dataLoaded: false; - } + dataLoaded: false; + useHJSON: boolean; + } | { - dataLoaded: true; - kvData: Record; - code: string; - }; + dataLoaded: true; + kvData: Record; + code: string; + useHJSON: boolean; + }; export class KVEditor extends Component { constructor() { super(); + // TODO: add a global use Hjson option to settings for default this.state = { dataLoaded: false, + useHJSON: false, }; } @@ -34,7 +66,7 @@ export class KVEditor extends Component { if (!this.state.dataLoaded) return; const editorContent = this.state.code; - if (!verifyJSONString(editorContent)) { + if (!isValidJSON(editorContent, this.state.useHJSON)) { setErrorText(i18next.t("kv_sec_edit_invalid_json_err")); return; } @@ -43,7 +75,7 @@ export class KVEditor extends Component { this.props.baseMount, this.props.secretPath.map((e) => e + "/"), this.props.secretItem, - JSON.parse(editorContent) as unknown as Record, + parseJSON(editorContent, this.hJSONToggleRef.current.checked), ); window.history.back(); } @@ -54,33 +86,31 @@ export class KVEditor extends Component { }); } - loadData(): void { - void this.props.api - .getSecret( - this.props.baseMount, - this.props.secretPath.map((e) => e + "/"), - this.props.secretItem, - ) - .then((kvData) => { - this.setState({ - dataLoaded: true, - kvData: kvData, - code: this.getStringKVData(kvData), - }); - }); - return; + async loadData() { + let kvData = await this.props.api.getSecret( + this.props.baseMount, + this.props.secretPath.map((e) => e + "/"), + this.props.secretItem, + ) + this.setState({ + dataLoaded: true, + kvData: kvData, + code: this.getStringKVData(kvData) + }); } - componentDidMount(): void { + async componentDidMount() { if (!this.state.dataLoaded) { - this.loadData(); + await this.loadData(); } } getStringKVData(data: Record): string { - return JSON.stringify(Object.fromEntries(sortedObjectMap(data)), null, 4); + return dumpJSON(Object.fromEntries(sortedObjectMap(data)), 4, this.state.useHJSON); } + hJSONToggleRef = createRef() + render(): JSX.Element { if (!this.state.dataLoaded) { return

{i18next.t("content_loading")}

; @@ -88,9 +118,15 @@ export class KVEditor extends Component { return (
+ + { + this.setState({useHJSON: this.hJSONToggleRef.current.checked}) + }} /> + +

this.onCodeUpdate(code)} diff --git a/webpack-dev.config.js b/webpack-dev.config.js index 9d390a1..4b0f4ef 100644 --- a/webpack-dev.config.js +++ b/webpack-dev.config.js @@ -34,6 +34,7 @@ module.exports = { resolve: { modules: ['node_modules'], extensions: ['.tsx', '.ts', '.js', ".mjs"], + alias: {os: false} }, module: { diff --git a/webpack.config.js b/webpack.config.js index b3c4bd4..88764e2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -60,6 +60,7 @@ module.exports = { resolve: { modules: ['node_modules'], extensions: ['.tsx', '.ts', '.js', ".mjs"], + alias: {os: false} }, module: {