Skip to content

Commit 2b9042e

Browse files
authored
Merge pull request #358 from khassel/config
update configuration section and add secrets
2 parents 7b7016e + 6a1097b commit 2b9042e

4 files changed

Lines changed: 178 additions & 21 deletions

File tree

.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export default defineConfig({
7272
collapsed: true,
7373
items: [
7474
{ text: "Introduction", link: "/configuration/introduction" },
75+
{ text: "Secrets", link: "/configuration/secrets" },
7576
{
7677
text: "Autostart your MagicMirror²",
7778
link: "/configuration/autostart",

configuration/introduction.md

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ After the above options, you will then add modules. See
7171
There are two environment variables that override part or all of config.js. They
7272
are:
7373

74-
| Environment Variable Name | Use |
75-
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
76-
| MM_CONFIG_FILE | This specifies an alternate configuration file for the system. This is useful when running multiple mirrors on the same device. This does not work with the template option below. NOTE: this file **_MUST_** be located in a directory within the MagicMirror directory. Ideally, place any config file in the config subdirectory. |
77-
| MM_PORT | This specifies an alternate TCP/IP port, overriding "port" item within the config file. This is useful for testing to see if the product will run using another port. |
78-
| mmFetchTimeout | time in milliseconds for fetch timeout. default (30000) <br><br>this value can be used to adjust the nodejs fetch function timeout value for all node_helper modules that use fetch() |
74+
| Environment Variable Name | Use |
75+
| ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
76+
| MM_CONFIG_FILE | This specifies an alternate configuration file for the system. This is useful when running multiple mirrors on the same device. NOTE: this file **_MUST_** be located in a directory within the MagicMirror directory. Ideally, place any config file in the config subdirectory. |
77+
| MM_PORT | This specifies an alternate TCP/IP port, overriding "port" item within the config file. This is useful for testing to see if the product will run using another port. |
78+
| mmFetchTimeout | time in milliseconds for fetch timeout. default (30000) <br><br>this value can be used to adjust the nodejs fetch function timeout value for all node_helper modules that use fetch() |
7979

8080
#### Examples of use
8181

@@ -117,18 +117,17 @@ node --run config:check
117117
[26.12.2023 18:13.13.062] [INFO] Your configuration file doesn't contain syntax errors :)
118118
```
119119

120-
### Configuration Template system
120+
### Environment variables inside the configuration file
121121

122-
`config.js.template` can be used instead of `config.js`. This allows you to use
123-
variables to replace hardcoded options. When starting MagicMirror² a `config.js`
124-
is created from `config.js.template` and the variables are resolved. This is
125-
most useful for tech support provided on the
122+
Since MagicMirror² version `v2.35.0` curly braced bash environment variable are
123+
allowed inside the `config.js` file. This allows you to use variables to replace
124+
hardcoded options. When starting MagicMirror² the variables are resolved. This
125+
is most useful for tech support provided on the
126126
[forums](http://forum.magicmirror.builders) and sharing your configuration.
127-
Note: You cannot use this with MM_CONFIG_FILE above at this time.
128127

129128
Variables must be inserted as `${MY_VARIABLE}`, examples:
130129

131-
`config.js.template`:
130+
`config.js`:
132131

133132
```js
134133
let config = {
@@ -140,9 +139,7 @@ let config = {
140139
if (typeof module !== "undefined") {module.exports = config;}
141140
```
142141

143-
would become
144-
145-
`config.js`:
142+
would be translated to
146143

147144
```js
148145
let config = {
@@ -163,8 +160,8 @@ variable is defined in both ways the linux environment variable is used.
163160

164161
#### Using a `config.env` file
165162

166-
This file must be in the same folder as the `config.js.template` and contains
167-
the variables, using the example from above:
163+
This file must be in the same folder as the `config.js` and contains the
164+
variables, using the example from above:
168165

169166
File content of `config.env`:
170167

@@ -176,7 +173,7 @@ MY_HTTPS=false
176173

177174
#### Using linux environment variables
178175

179-
define them before you start MagicMirror², in a bash script, for example:
176+
Define them before you start MagicMirror², in a bash script, for example:
180177

181178
```bash
182179
cd ~/MagicMirror
@@ -272,14 +269,14 @@ if (typeof module !== "undefined") {
272269
}
273270
```
274271
275-
#### config.js.template example
272+
#### config.js with variables
276273
277274
User likes to help German language users in the forums. As such, he wants to be
278275
able to paste bits of his config.js into the forums to show as an example, but
279276
don't want to share his private data, and has a hard time remembering to remove
280277
them from the config.js file.
281278
282-
`config.js.template`:
279+
`config.js`:
283280
284281
```js
285282
let config = {

configuration/secrets.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# Secrets
2+
3+
When MagicMirror² was designed, no one thought about secrets.
4+
5+
However, there are plenty of parameters worth protecting, such as:
6+
7+
- API keys (e.g. weather)
8+
- Tokens in URLs
9+
- Private calendar URLs
10+
- Position information (latitude and longitude)
11+
- ...
12+
13+
::: warning NOTE
14+
15+
Due to its design, this data is also displayed in the web browser, for example,
16+
in the `/config` subpath.
17+
18+
Therefore, be careful when sharing your MagicMirror² website with others. Anyone
19+
with access to the site can also access the secrets.
20+
21+
:::
22+
23+
Beginning with MagicMirror² `v2.35.0` we offer beta support for secrets.
24+
25+
This is based on
26+
[environment variables inside the configuration file](/configuration/introduction.html#environment-variables-inside-the-configuration-file).
27+
28+
::: warning NOTE
29+
30+
"Beta" means we offer no guarantee that the methods described below for
31+
protecting sensitive information will actually work. Use at your own risk.
32+
33+
:::
34+
35+
## Different module types
36+
37+
There are two types of modules in MagicMirror²:
38+
39+
- browser-only
40+
- server-side and browser-side
41+
42+
Why is this mentioned? Because secrets can only be protected server-side.
43+
44+
::: warning NOTE
45+
46+
In any case, you should carefully examine the modules you are using.
47+
Theoretically, a malicious module could intercept the entire configuration,
48+
including all secrets, and send it somewhere else.
49+
50+
:::
51+
52+
## Using secrets in server-side modules
53+
54+
You have to add a new parameter in `config.js`:
55+
56+
```js
57+
let config = {
58+
...
59+
hideConfigSecrets: true,
60+
...
61+
};
62+
```
63+
64+
After a restart MagicMirror² will not send environment variables beginning with
65+
`SECRET_` to the clients (browsers).
66+
67+
### Example
68+
69+
The MMM-Strava module displays activities and needs 2 parameters `client_id` and
70+
`client_secret` to get the data.
71+
72+
In this example the 2 parameters are set with 2 normal environment variables
73+
`STRAVA_CLIENT_ID` and `STRAVA_API_KEY`:
74+
75+
```js
76+
let config = {
77+
...
78+
hideConfigSecrets: true,
79+
...
80+
modules: [
81+
{
82+
module: "MMM-Strava",
83+
header: "Strava",
84+
position: "bottom_left",
85+
config: {
86+
client_id: "${STRAVA_CLIENT_ID}",
87+
client_secret: "${STRAVA_API_KEY}",
88+
activities: ["ride"],
89+
period: "recent",
90+
stats: ["count", "distance", "elevation", "achievements"],
91+
auto_rotate: true,
92+
updateInterval: 20000,
93+
reloadInterval: 3600000,
94+
showPrivateStats: true,
95+
limitPrivateStats: 1200,
96+
digits: 0
97+
}
98+
},
99+
...
100+
]
101+
};
102+
```
103+
104+
This setup is unsafe, you can see the contents of the 2 environment variables in
105+
the browser.
106+
107+
To be safe, you have to use environment variables called
108+
`SECRET_STRAVA_CLIENT_ID` and `SECRET_STRAVA_API_KEY`. The browser has no access
109+
to the content of variables prefixed with `SECRET_`, the content of e.g.
110+
`SECRET_STRAVA_CLIENT_ID` is displayed as `**SECRET_STRAVA_CLIENT_ID**`.
111+
112+
## Using secrets on the browser-side
113+
114+
Yes, we wrote above that this isn't possible. However, for some applications it
115+
might work with a workaround.
116+
117+
There are modules that use a map (e.g. MMM-RAIN-MAP, MMM-Flights) and the data
118+
required for this map is of course retrieved in the browser.
119+
120+
Some map services, such as MapBox, offer free maps, but often require an access
121+
token in the URL.
122+
123+
Example:
124+
125+
```js
126+
let config = {
127+
...
128+
hideConfigSecrets: true,
129+
...
130+
modules: [
131+
{
132+
module: "MMM-Flights",
133+
position: "top_left",
134+
config: {
135+
mapUrl: "https://api.mapbox.com/styles/v1/username/mapId/tiles/{z}/{x}/{y}?access_token=abc"
136+
},
137+
},
138+
...
139+
]
140+
};
141+
```
142+
143+
To protect sensitive information in the above url you can change it to
144+
145+
`mapUrl: "https://api.mapbox.com/styles/v1/${SECRET_MAPBOX_ID}/tiles/{z}/{x}/{y}?access_token=${SECRET_MAPBOX_TOKEN}"`
146+
147+
This will protect the secrets but the modules won't work. The workaround is to
148+
use the internal cors proxy. This means that the traffic does not go directly
149+
from the browser to the outside, but first to the MagicMirror² server, which
150+
acts as a proxy here:
151+
152+
`mapUrl: "/cors?url=https://api.mapbox.com/styles/v1/${SECRET_MAPBOX_ID}/tiles/{z}/{x}/{y}?access_token=${SECRET_MAPBOX_TOKEN}"`
153+
154+
Behind the scenes the server substitutes the variables before fetching the data.

cspell.config.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"words": [
55
"anyfileorfolder",
66
"apikey",
7+
"Autologin",
78
"Autorestart",
89
"bouncyflip",
910
"clientonly",
@@ -12,6 +13,7 @@
1213
"dateheaders",
1314
"datetype",
1415
"Deepwiki",
16+
"defaultmodules",
1517
"endfor",
1618
"envcanada",
1719
"exploader",
@@ -22,13 +24,14 @@
2224
"inclusivity",
2325
"infobars",
2426
"intpx",
27+
"journalctl",
2528
"LXDE",
2629
"lxpanel",
2730
"lxsession",
2831
"magicmirror",
2932
"MAPBOX",
30-
"miletorix",
3133
"meteo",
34+
"miletorix",
3235
"modulename",
3336
"myclass",
3437
"mycroft",
@@ -50,6 +53,7 @@
5053
"pmedian",
5154
"pmin",
5255
"prio",
56+
"raspi",
5357
"RGBA",
5458
"sdetweil",
5559
"serveronly",
@@ -74,6 +78,7 @@
7478
"weathergov",
7579
"weatherutils",
7680
"windspeed",
81+
"XAUTHORITY",
7782
"xlarge",
7883
"xscreensaver",
7984
"xsmall",

0 commit comments

Comments
 (0)