diff --git a/.gitignore b/.gitignore index ee51c8812..956e59f43 100644 --- a/.gitignore +++ b/.gitignore @@ -22,5 +22,6 @@ yarn-error.log* # App configuration config.yml +secrets.yml .drone.yml \ No newline at end of file diff --git a/docs/configuration.md b/docs/configuration.md index e43a8b811..6468b1cf1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -194,3 +194,29 @@ The `/assets/manifest.json` can also be edited to change the app (pwa) name, des ## PWA Icons See icons documentation [here](https://github.com/bastienwirtz/homer/blob/main/public/assets/icons/README.md). + + +## Importing Secrets + +You can import sensitive information such as API keys or passwords into your `config.yml` file securely using the `!secret` keyword. The corresponding tokens are stored in the `secrets.yml` file. This approach allows you to keep confidential information separate, eliminating the need to expose sensitive information directly in your configuration. + + +### Example: + +In your `secrets.yml` file: + +```yaml +api_key: your_super_secret_api_key +db_password: your_secure_database_password +``` + +In your `config.yml` file: + +```yaml +services: + - name: "Example Service" + api_key: !secret api_key + database: + password: !secret db_password +# ... +``` \ No newline at end of file diff --git a/public/assets/config-demo.yml.dist b/public/assets/config-demo.yml.dist index ac2b41182..9e8425552 100644 --- a/public/assets/config-demo.yml.dist +++ b/public/assets/config-demo.yml.dist @@ -83,7 +83,7 @@ services: node: "node1" warning_value: 50 danger_value: 80 - api_token: "xxxxxxxxxxxx" + api_token: !secret proxmox_api - name: "An awesome app" logo: "assets/tools/sample.png" subtitle: "Bookmark example" @@ -95,7 +95,7 @@ services: items: - name: "Octoprint" logo: "https://cdn-icons-png.flaticon.com/512/3112/3112529.png" - apikey: "xxxxxxxxxxxx" + apikey: !secret octoprint_api endpoint: "https://homer-demo-content.netlify.app/octoprint" type: "OctoPrint" - name: "Example item" @@ -107,7 +107,7 @@ services: target: "_blank" - name: "Weather" location: "Lyon" - apikey: "xxxxxxxxxxxx" # insert your own API key here. Request one from https://openweathermap.org/api. + apikey: !secret weather_api # insert your own API key here. Request one from https://openweathermap.org/api. units: "metric" endpoint: "https://homer-demo-content.netlify.app/openweather/weather" type: "OpenWeather" diff --git a/public/assets/secrets.yml b/public/assets/secrets.yml new file mode 100644 index 000000000..6283cb5cf --- /dev/null +++ b/public/assets/secrets.yml @@ -0,0 +1,4 @@ +some_password: welcome # include it in your config.yml by using !secret some_password +proxmox_api: xxxxxxxxxxxx +octoprint_api: xxxxxxxxxxxx +weather_api: xxxxxxxxxxxx \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index e84f08359..4217e6055 100644 --- a/src/App.vue +++ b/src/App.vue @@ -245,7 +245,24 @@ export default { return response .text() .then((body) => { - return parse(body, { merge: true }); + return fetch("assets/secrets.yml") + .then((secretsResponse) => { + if (secretsResponse.status == 404 || secretsResponse.redirected) { + return {}; + } + if (!secretsResponse.ok) { + throw Error(`${secretsResponse.statusText}: ${secretsResponse.body}`); + } + return secretsResponse.text(); + }) + .then((secretsText) => { + const secrets = parse(secretsText); + let replacedBody = body; + Object.entries(secrets).forEach(([key, token]) => { + replacedBody = replacedBody.replace(new RegExp(`!secret ${key}`, "g"), token); + }); + return parse(replacedBody, { merge: true }); + }); }) .then(function (config) { if (config.externalConfig) {