JSON config schema improvements.

Ylian Saint-Hilaire committed Jun 15, 2020 at 13:08 UTC 020e82dc08d236a7cd305e854e244b736eb608ae
3 files changed +431 -425
meshcentral-config-schema.json
+293 -287
@@ -7,20 +7,20 @@
7 "settings": {
8 "type": "object",
9 "properties": {
10 - "Cert": { "type": "string" },
11 - "MongoDb": { "type": "string" },
12 - "MongoDbName": { "type": "string" },
13 - "MongoDbChangeStream": { "type": "boolean" },
14 - "MongoDumpPath": { "type": "string" },
10 + "cert": { "type": "string" },
11 + "mongoDb": { "type": "string" },
12 + "mongoDbName": { "type": "string" },
13 + "mongoDbChangeStream": { "type": "boolean" },
14 + "mongoDumpPath": { "type": "string" },
15 "WANonly": { "type": "boolean", "default": false },
16 "LANonly": { "type": "boolean", "default": false },
17 - "SessionTime": { "type": "integer" },
18 - "SessionKey": { "type": "string" },
19 - "SessionSameSite": { "type": "string" },
20 - "DbEncryptKey": { "type": "string" },
21 - "DbRecordsEncryptKey": { "type": "string" },
22 - "DbRecordsDecryptKey": { "type": "string" },
23 - "DbExpire": {
17 + "sessionTime": { "type": "integer" },
18 + "sessionKey": { "type": "string" },
19 + "sessionSameSite": { "type": "string" },
20 + "dbEncryptKey": { "type": "string" },
21 + "dbRecordsEncryptKey": { "type": "string" },
22 + "dbRecordsDecryptKey": { "type": "string" },
23 + "dbExpire": {
24 "type": "object",
25 "properties": {
26 "events": { "type": "integer" },
@@ -28,45 +28,46 @@
28 "statsevents": { "type": "integer" }
29 }
30 },
31 - "Port": { "type": "integer", "minimum": 1, "maximum": 65535 },
32 - "PortBind": { "type": "string" },
33 - "AliasPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
34 - "RedirPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
35 - "RedirPortBind": { "type": "string" },
36 - "RedirAliasPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
37 - "AgentPort": { "type": "integer", "minimum": 1, "maximum": 65535, "description": "When set, enabled a new HTTPS server port that only accepts agent connections" },
38 - "AgentPortBind": { "type": "string", "description": "When set, binds the agent port to a specific network interface" },
39 - "AgentAliasPort": { "type": "integer", "minimum": 1, "maximum": 65535, "description": "When set, indicates the actual publically visible agent-only port. If not set, the AgentPort value is used" },
40 - "AgentAliasDNS": { "type": "string", "format": "hostname", "description": "When set, specified the DNS name used by agents to connect to the agent-only port" },
41 - "AgentPortTls": { "type": "boolean", "default": true, "description": "Indicates if the agent-only port must perform TLS, this should be set to false if TLS is performed in front of this server" },
42 - "ExactPorts": { "type": "boolean", "default": false },
43 - "AllowLoginToken": { "type": "boolean", "default": false },
44 - "AllowFraming": { "type": "boolean", "default": false },
45 - "CookieIpCheck": { "type": "boolean" },
46 - "CookieEncoding": { "type": "string", "enum": [ "hex", "base64" ], "default": "base64" },
47 - "WebRTC": { "type": "boolean", "default": false, "description": "When enabled, allows use of WebRTC to allow direct network traffic between the agent and browser" },
48 - "Nice404": { "type": "boolean" },
49 - "ClickOnce": { "type": "boolean" },
50 - "SelfUpdate": { "type": "boolean", "default": false, "description": "When true, this server will attempt to self-update everyday after midnight." },
51 - "BrowserPing": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the browser at x seconds interval and expects a response from the browser." },
52 - "BrowserPong": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the browser at x seconds interval." },
53 - "AgentPing": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the agent at x seconds interval and expects a response from the agent." },
54 - "AgentPong": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the agent at x seconds interval." },
55 - "AgentIdleTimeout": { "type": "integer", "minimum": 1 },
56 - "MeshErrorLogPath": { "type": "string" },
57 - "NpmPath": { "type": "string" },
58 - "NpmProxy": { "type": "string", "format": "uri" },
59 - "AllowHighQualityDesktop": { "type": "boolean", "default": true },
60 - "DesktopMultiplex": { "type": "boolean", "default": false },
61 - "UserAllowedIP": { "type": [ "string", "array" ] },
62 - "UserBlockedIP": { "type": [ "string", "array" ] },
63 - "AgentAllowedIP": { "type": [ "string", "array" ] },
64 - "AgentBlockedIP": { "type": [ "string", "array" ] },
65 - "AuthLog": { "type": "string" },
66 - "ManageAllDeviceGroups": { "type": "array", "items": [ { "type": "string" } ] },
67 - "ManageCrossDomain": { "type": "array", "items": [ { "type": "string" } ] },
68 - "LocalDiscovery": {
31 + "port": { "type": "integer", "minimum": 1, "maximum": 65535 },
32 + "portBind": { "type": "string", "description": "When set, bind the HTTPS main port to a specific network address." },
33 + "aliasPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
34 + "redirPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
35 + "redirPortBind": { "type": "string", "description": "When set, bind the HTTP redirection port to a specific network address." },
36 + "redirAliasPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
37 + "agentPort": { "type": "integer", "minimum": 1, "maximum": 65535, "description": "When set, enabled a new HTTPS server port that only accepts agent connections." },
38 + "agentPortBind": { "type": "string", "description": "When set, binds the agent port to a specific network interface." },
39 + "agentAliasPort": { "type": "integer", "minimum": 1, "maximum": 65535, "description": "When set, indicates the actual publically visible agent-only port. If not set, the AgentPort value is used." },
40 + "agentAliasDNS": { "type": "string", "format": "hostname", "description": "When set, specified the DNS name used by agents to connect to the agent-only port." },
41 + "agentPortTls": { "type": "boolean", "default": true, "description": "Indicates if the agent-only port must perform TLS, this should be set to false if TLS is performed in front of this server." },
42 + "exactPorts": { "type": "boolean", "default": false },
43 + "allowLoginToken": { "type": "boolean", "default": false },
44 + "allowFraming": { "type": "boolean", "default": false },
45 + "cookieIpCheck": { "type": "boolean" },
46 + "cookieEncoding": { "type": "string", "enum": [ "hex", "base64" ], "default": "base64", "description": "Encoding format of cookies in the HTTP headers, this is typically Base64 but some reverse proxies will require HEX." },
47 + "webRTC": { "type": "boolean", "default": false, "description": "When enabled, allows use of WebRTC to allow direct network traffic between the agent and browser." },
48 + "nice404": { "type": "boolean", "default": true, "description": "By default, a nice looking 404 error page is displayed when needed. Set this to false to disable it." },
49 + "clickOnce": { "type": "boolean", "default": true, "description": "By default Microsoft ClickOnce support is enabled allowing connection routing from the web site on IE browser and browsers with ClickOnce add-in." },
50 + "selfUpdate": { "type": "boolean", "default": false, "description": "When true, this server will attempt to self-update everyday after midnight." },
51 + "browserPing": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the browser at x seconds interval and expects a response from the browser." },
52 + "browserPong": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the browser at x seconds interval." },
53 + "agentPing": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the agent at x seconds interval and expects a response from the agent." },
54 + "agentPong": { "type": "integer", "minimum": 1, "description": "When specified, sends data to the agent at x seconds interval." },
55 + "agentIdleTimeout": { "type": "integer", "minimum": 1 },
56 + "meshErrorLogPath": { "type": "string" },
57 + "npmPath": { "type": "string" },
58 + "npmProxy": { "type": "string", "format": "uri" },
59 + "allowHighQualityDesktop": { "type": "boolean", "default": true },
60 + "desktopMultiplex": { "type": "boolean", "default": false },
61 + "userAllowedIP": { "type": [ "string", "array" ] },
62 + "userBlockedIP": { "type": [ "string", "array" ] },
63 + "agentAllowedIP": { "type": [ "string", "array" ] },
64 + "agentBlockedIP": { "type": [ "string", "array" ] },
65 + "authLog": { "type": "string" },
66 + "manageAllDeviceGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
67 + "manageCrossDomain": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
68 + "localDiscovery": {
69 "type": "object",
70 + "description": "When this server is in LAN mode, you may discover this server using a multicast discovery tool. When discovery happens, the name and info fields are sent back to the discovery tool.",
71 "additionalProperties": false,
72 "properties": {
73 "name": { "type": "string" },
@@ -74,29 +75,26 @@
75 },
76 "required": [ "name", "info" ]
77 },
77 - "TlsOffload": { "type": [ "string", "boolean" ], "default": false },
78 - "TrustedProxy": { "type": "string" },
79 - "MpsPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
80 - "MpsPortBind": { "type": "string" },
81 - "MpsAliasPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
82 - "MpsAliasHost": { "type": "string" },
83 - "MpsTlsOffload": { "type": "boolean", "default": false },
84 - "No2FactorAuth": { "type": "boolean" },
85 - "Log": { "type": "string" },
78 + "tlsOffload": { "type": [ "string", "boolean" ], "default": false },
79 + "trustedProxy": { "type": "string" },
80 + "mpsPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
81 + "mpsPortBind": { "type": "string" },
82 + "mpsAliasPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
83 + "mpsAliasHost": { "type": "string" },
84 + "mpsTlsOffload": { "type": "boolean", "default": false },
85 + "no2FactorAuth": { "type": "boolean" },
86 + "log": { "type": "string" },
87 "syslog": { "type": "string" },
88 "syslogauth": { "type": "string" },
89 "syslogjson": { "type": "string" },
89 - "WebRtConfig": {
90 + "webrtcConfig": {
91 "type": "object",
92 "properties": {
92 - "iceServers": {
93 - "type": "array",
94 - "items": [ { "type": "object", "properties": { "urls": { "type": "string" } }, "required": [ "urls" ] } ]
95 - }
93 + "iceServers": { "type": "array", "uniqueItems": true, "items": { "type": "object", "properties": { "urls": { "type": "string" } }, "required": [ "urls" ] } }
94 },
95 "required": [ "iceServers" ]
96 },
99 - "AutoBackup": {
97 + "autoBackup": {
98 "type": "object",
99 "properties": {
100 "backupIntervalHours": { "type": "integer" },
@@ -105,8 +103,8 @@
103 "backupPath": { "type": "string" }
104 }
105 },
108 - "Redirects": { "type": "object" },
109 - "MaxInvalidLogin": {
106 + "redirects": { "type": "object" },
107 + "maxInvalidLogin": {
108 "type": "object",
109 "additionalProperties": false,
110 "properties": {
@@ -115,247 +113,243 @@
113 "coolofftime": { "type": "integer" }
114 }
115 },
118 - "Plugins": {
116 + "plugins": {
117 "type": "object",
118 "properties": { "enabled": { "type": "boolean" } },
119 "required": [ "enabled" ]
120 }
121 }
122 },
125 - "domaindefaults": { "type": "object" },
123 + "domaindefaults": { "$ref": "#/properties/domains/items" },
124 "domains": {
125 "type": "object",
128 - "properties": {
129 - "": {
130 - "type": "object",
131 - "properties": {
132 - "Title": { "type": "string" },
133 - "Title2": { "type": "string" },
134 - "TitlePicture": { "type": "string" },
135 - "UserQuota": { "type": "integer" },
136 - "MeshQuota": { "type": "integer" },
137 - "Minify": { "type": "boolean" },
138 - "NewAccounts": { "type": "boolean" },
139 - "NewAccountsUserGroups": { "type": "array", "items": [ { "type": "string" } ] },
140 - "UserNameIsEmail": { "type": "boolean" },
141 - "NewAccountEmailDomains": { "type": "array", "items": [ { "type": "string" } ] },
142 - "NewAccountsRights": { "type": "array", "items": [ { "type": "string" } ] },
143 - "WelcomeText": { "type": "string" },
144 - "WelcomePicture": { "type": "string" },
145 - "Hide": { "type": "integer" },
146 - "Footer": { "type": "string" },
147 - "CertUrl": { "type": "string", "format": "uri" },
148 - "PasswordRequirements": {
149 - "type": "object",
150 - "properties": {
151 - "min": { "type": "integer" },
152 - "max": { "type": "integer" },
153 - "upper": { "type": "integer" },
154 - "lower": { "type": "integer" },
155 - "numeric": { "type": "integer" },
156 - "nonalpha": { "type": "integer" },
157 - "reset": { "type": "integer" },
158 - "force2factor": { "type": "boolean" },
159 - "skip2factor": { "type": "string" }
160 - }
161 - },
162 - "AgentInviteCodes": { "type": "boolean", "default": false },
163 - "AgentNoProxy": { "type": "boolean", "default": false },
164 - "GeoLocation": { "type": "boolean", "default": false },
165 - "novnc": { "type": "boolean", "default": true },
166 - "mstsc": {
167 - "type": "boolean",
168 - "default": false
169 - },
170 - "CustomUI": { "type": "object" },
171 - "ConsentMessages": {
172 - "type": "object",
173 - "additionalProperties": false,
174 - "properties": {
175 - "Title": { "type": "string" },
176 - "Desktop": { "type": "string" },
177 - "Terminal": { "type": "string" },
178 - "Files": { "type": "string" }
179 - }
180 - },
181 - "NotificationMessages": {
182 - "type": "object",
183 - "additionalProperties": false,
184 - "properties": {
185 - "Title": { "type": "string" },
186 - "Desktop": { "type": "string" },
187 - "Terminal": { "type": "string" },
188 - "Files": { "type": "string" }
189 - }
190 - },
191 - "UserAllowedIP": { "type": "string" },
192 - "UserBlockedIP": { "type": "string" },
193 - "AgentAllowedIP": { "type": "string" },
194 - "AgentBlockedIP": { "type": "string" },
195 - "UserSessionIdleTimeout": { "type": "integer" },
196 - "UserConsentFlags": { "type": "integer" },
197 - "UrlSwitching": { "type": "boolean" },
198 - "DesktopPrivacyBarText": { "type": "string" },
199 - "Limits": {
200 - "type": "object",
201 - "properties": {
202 - "MaxDevices": { "type": "integer" },
203 - "MaxUserAccounts": { "type": "integer" },
204 - "MaxUserSessions": { "type": "integer" },
205 - "MaxAgentSessions": { "type": "integer" },
206 - "MaxSingleUserSessions": { "type": "integer" }
207 - }
208 - },
209 - "AmtAcmActivation": {
210 - "type": "object",
211 - "properties": {
212 - "log": { "type": "string" },
213 - "certs": {
126 + "items": {
127 + "type": "object",
128 + "properties": {
129 + "title": { "type": "string" },
130 + "title2": { "type": "string" },
131 + "titlePicture": { "type": "string" },
132 + "userQuota": { "type": "integer" },
133 + "meshQuota": { "type": "integer" },
134 + "minify": { "type": "boolean", "default": false, "description": "When enabled, the server will send reduced sided web pages." },
135 + "newAccounts": { "type": "boolean" },
136 + "newAccountsUserGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
137 + "userNameIsEmail": { "type": "boolean", "default": false, "description": "When enabled, the username of each account is also the email address of the account." },
138 + "newAccountEmailDomains": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
139 + "newAccountsRights": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
140 + "welcomeText": { "type": "string" },
141 + "welcomePicture": { "type": "string" },
142 + "hide": { "type": "integer" },
143 + "footer": { "type": "string" },
144 + "certUrl": { "type": "string", "format": "uri" },
145 + "passwordRequirements": {
146 + "type": "object",
147 + "properties": {
148 + "min": { "type": "integer" },
149 + "max": { "type": "integer" },
150 + "upper": { "type": "integer" },
151 + "lower": { "type": "integer" },
152 + "numeric": { "type": "integer" },
153 + "nonalpha": { "type": "integer" },
154 + "reset": { "type": "integer" },
155 + "force2factor": { "type": "boolean" },
156 + "skip2factor": { "type": "string" }
157 + }
158 + },
159 + "agentInviteCodes": { "type": "boolean", "default": false },
160 + "agentNoProxy": { "type": "boolean", "default": false },
161 + "geoLocation": { "type": "boolean", "default": false },
162 + "novnc": { "type": "boolean", "default": true },
163 + "mstsc": { "type": "boolean", "default": false },
164 + "customUI": { "type": "object" },
165 + "consentMessages": {
166 + "type": "object",
167 + "additionalProperties": false,
168 + "properties": {
169 + "Title": { "type": "string" },
170 + "Desktop": { "type": "string" },
171 + "Terminal": { "type": "string" },
172 + "Files": { "type": "string" }
173 + }
174 + },
175 + "notificationMessages": {
176 + "type": "object",
177 + "additionalProperties": false,
178 + "properties": {
179 + "Title": { "type": "string" },
180 + "Desktop": { "type": "string" },
181 + "Terminal": { "type": "string" },
182 + "Files": { "type": "string" }
183 + }
184 + },
185 + "userAllowedIP": { "type": "string" },
186 + "userBlockedIP": { "type": "string" },
187 + "agentAllowedIP": { "type": "string" },
188 + "agentBlockedIP": { "type": "string" },
189 + "userSessionIdleTimeout": { "type": "integer" },
190 + "userConsentFlags": { "type": "integer" },
191 + "urlSwitching": { "type": "boolean" },
192 + "desktopPrivacyBarText": { "type": "string" },
193 + "limits": {
194 + "type": "object",
195 + "additionalProperties": false,
196 + "properties": {
197 + "MaxDevices": { "type": "integer" },
198 + "MaxUserAccounts": { "type": "integer" },
199 + "MaxUserSessions": { "type": "integer" },
200 + "MaxAgentSessions": { "type": "integer" },
201 + "MaxSingleUserSessions": { "type": "integer" }
202 + }
203 + },
204 + "amtAcmActivation": {
205 + "type": "object",
206 + "additionalProperties": false,
207 + "properties": {
208 + "log": { "type": "string" },
209 + "certs": {
210 + "type": "object",
211 + "additionalProperties": {
212 "type": "object",
215 - "additionalProperties": {
216 - "type": "object",
217 - "properties": {
218 - "certfiles": { "type": "array", "items": [ { "type": "string" } ] },
219 - "keyfile": { "type": "string" }
220 - },
221 - "required": [ "certfiles", "keyfile" ]
222 - }
213 + "additionalProperties": false,
214 + "properties": {
215 + "certfiles": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
216 + "keyfile": { "type": "string" }
217 + },
218 + "required": [ "certfiles", "keyfile" ]
219 }
220 }
221 },
226 - "Redirects": {
227 - "type": "object",
228 - "additionalProperties": { "type": "string" }
229 - },
230 - "Yubikey": {
231 - "type": "object",
232 - "properties": {
233 - "id": { "type": "string" },
234 - "secret": { "type": "string" },
235 - "proxy": { "type": "string" }
236 - },
237 - "required": [ "id", "secret" ]
222 + "required": [ "certs" ]
223 + },
224 + "redirects": {
225 + "type": "object",
226 + "additionalProperties": { "type": "string" }
227 + },
228 + "yubikey": {
229 + "type": "object",
230 + "additionalProperties": false,
231 + "properties": {
232 + "id": { "type": "string" },
233 + "secret": { "type": "string" },
234 + "proxy": { "type": "string", "format": "uri" }
235 },
239 - "AgentConfig": {
240 - "type": "array",
241 - "items": [ { "type": "string" } ]
236 + "required": [ "id", "secret" ]
237 + },
238 + "httpHeaders": { "type": "object", "additionalProperties": { "type": "string" } },
239 + "agentConfig": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
240 + "sessionRecording": {
241 + "type": "object",
242 + "additionalProperties": false,
243 + "properties": {
244 + "filepath": { "type": "string" },
245 + "index": { "type": "boolean", "default": false },
246 + "maxRecordings": { "type": "integer" },
247 + "maxRecordingSizeMegabytes": { "type": "integer" },
248 + "protocols": { "type": "array", "uniqueItems": true, "items": { "type": "integer" } }
249 },
243 - "SessionRecording": {
244 - "type": "object",
245 - "properties": {
246 - "filepath": { "type": "string" },
247 - "index": { "type": "boolean", "default": false },
248 - "maxRecordings": { "type": "integer" },
249 - "maxRecordingSizeMegabytes": { "type": "integer" },
250 - "protocols": {
251 - "type": "array",
252 - "items": [ { "type": "integer" } ]
253 - }
250 + "required": [ "protocols" ]
251 + },
252 + "authStrategies": {
253 + "type": "object",
254 + "additionalProperties": false,
255 + "properties": {
256 + "twitter": {
257 + "type": "object",
258 + "additionalProperties": false,
259 + "properties": {
260 + "callbackurl": { "type": "string", "format": "uri" },
261 + "newAccounts": { "type": "boolean", "default": false },
262 + "newAccountsUserGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
263 + "clientid": { "type": "string" },
264 + "clientsecret": { "type": "string" }
265 + },
266 + "required": [ "clientid", "clientsecret" ]
267 },
255 - "required": [ "protocols" ]
256 - },
257 - "AuthStrategies": {
258 - "type": "object",
259 - "additionalProperties": false,
260 - "properties": {
261 - "twitter": {
262 - "type": "object",
263 - "additionalProperties": false,
264 - "properties": {
265 - "callbackurl": { "type": "string", "format": "uri" },
266 - "newAccounts": { "type": "boolean" },
267 - "newAccountsUserGroups": { "type": "array", "items": [ { "type": "string" } ] },
268 - "clientid": { "type": "string" },
269 - "clientsecret": { "type": "string" }
270 - },
271 - "required": [ "clientid", "clientsecret" ]
268 + "google": {
269 + "type": "object",
270 + "properties": {
271 + "callbackurl": { "type": "string", "format": "uri" },
272 + "newAccounts": { "type": "boolean", "default": false },
273 + "newAccountsUserGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
274 + "clientid": { "type": "string" },
275 + "clientsecret": { "type": "string" }
276 },
273 - "google": {
274 - "type": "object",
275 - "properties": {
276 - "callbackurl": { "type": "string", "format": "uri" },
277 - "newAccounts": { "type": "boolean" },
278 - "newAccountsUserGroups": { "type": "array", "items": [ { "type": "string" } ] },
279 - "clientid": { "type": "string" },
280 - "clientsecret": { "type": "string" }
281 - },
282 - "required": [ "clientid", "clientsecret" ]
277 + "required": [ "clientid", "clientsecret" ]
278 + },
279 + "github": {
280 + "type": "object",
281 + "properties": {
282 + "callbackurl": { "type": "string", "format": "uri" },
283 + "newAccounts": { "type": "boolean", "default": false },
284 + "newAccountsUserGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
285 + "clientid": { "type": "string" },
286 + "clientsecret": { "type": "string" }
287 },
284 - "github": {
285 - "type": "object",
286 - "properties": {
287 - "callbackurl": { "type": "string", "format": "uri" },
288 - "newAccounts": { "type": "boolean" },
289 - "newAccountsUserGroups": { "type": "array", "items": [ { "type": "string" } ] },
290 - "clientid": { "type": "string" },
291 - "clientsecret": { "type": "string" }
292 - },
293 - "required": [ "clientid", "clientsecret" ]
288 + "required": [ "clientid", "clientsecret" ]
289 + },
290 + "reddit": {
291 + "type": "object",
292 + "properties": {
293 + "callbackurl": { "type": "string", "format": "uri" },
294 + "newAccounts": { "type": "boolean", "default": false },
295 + "newAccountsUserGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
296 + "clientid": { "type": "string" },
297 + "clientsecret": { "type": "string" }
298 },
295 - "reddit": {
296 - "type": "object",
297 - "properties": {
298 - "callbackurl": { "type": "string", "format": "uri" },
299 - "newAccounts": { "type": "boolean" },
300 - "newAccountsUserGroups": { "type": "array", "items": [ { "type": "string" } ] },
301 - "clientid": { "type": "string" },
302 - "clientsecret": { "type": "string" }
303 - },
304 - "required": [ "clientid", "clientsecret" ]
299 + "required": [ "clientid", "clientsecret" ]
300 + },
301 + "azure": {
302 + "type": "object",
303 + "properties": {
304 + "callbackurl": { "type": "string", "format": "uri" },
305 + "newAccounts": { "type": "boolean", "default": false },
306 + "newAccountsUserGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
307 + "clientid": { "type": "string" },
308 + "clientsecret": { "type": "string" },
309 + "tenantid": { "type": "string" }
310 },
306 - "azure": {
307 - "type": "object",
308 - "properties": {
309 - "callbackurl": { "type": "string", "format": "uri" },
310 - "newAccounts": { "type": "boolean" },
311 - "newAccountsUserGroups": { "type": "array", "items": [ { "type": "string" } ] },
312 - "clientid": { "type": "string" },
313 - "clientsecret": { "type": "string" },
314 - "tenantid": { "type": "string" }
315 - },
316 - "required": [ "clientid", "clientsecret", "tenantid" ]
311 + "required": [ "clientid", "clientsecret", "tenantid" ]
312 + },
313 + "jumpcloud": {
314 + "type": "object",
315 + "properties": {
316 + "callbackurl": { "type": "string", "format": "uri" },
317 + "newAccounts": { "type": "boolean", "default": false },
318 + "newAccountsUserGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
319 + "entityid": { "type": "string" },
320 + "idpurl": { "type": "string", "format": "uri" },
321 + "cert": { "type": "string" }
322 },
318 - "jumpcloud": {
319 - "type": "object",
320 - "properties": {
321 - "callbackurl": { "type": "string", "format": "uri" },
322 - "newAccounts": { "type": "boolean" },
323 - "newAccountsUserGroups": { "type": "array", "items": [ { "type": "string" } ] },
324 - "entityid": { "type": "string" },
325 - "idpurl": { "type": "string" },
326 - "cert": { "type": "string" }
327 - },
328 - "required": [ "entityid", "idpurl", "cert" ]
323 + "required": [ "entityid", "idpurl", "cert" ]
324 + },
325 + "saml": {
326 + "type": "object",
327 + "properties": {
328 + "callbackurl": { "type": "string", "format": "uri" },
329 + "disableRequestedAuthnContext": { "type": "boolean" },
330 + "newAccounts": { "type": "boolean", "default": false },
331 + "newAccountsUserGroups": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
332 + "newAccountsRights": { "type": "array", "uniqueItems": true, "items": { "type": "string" } },
333 + "entityid": { "type": "string" },
334 + "idpurl": { "type": "string", "format": "uri" },
335 + "cert": { "type": "string" }
336 },
330 - "saml": {
331 - "type": "object",
332 - "properties": {
333 - "callbackurl": { "type": "string", "format": "uri" },
334 - "disableRequestedAuthnContext": { "type": "boolean" },
335 - "newAccounts": { "type": "boolean" },
336 - "newAccountsUserGroups": { "type": "array", "items": [ { "type": "string" } ] },
337 - "newAccountsRights": { "type": "array", "items": [ { "type": "string" } ] },
338 - "entityid": { "type": "string" },
339 - "idpurl": { "type": "string" },
340 - "cert": { "type": "string" }
341 - },
342 - "required": [ "entityid", "idpurl", "cert" ]
343 - }
337 + "required": [ "entityid", "idpurl", "cert" ]
338 }
339 }
340 }
341 }
342 }
343 },
350 - "letsencrypt": {
344 + "letsEncrypt": {
345 "title" : "Built-in Let's Encrypt support",
346 "description": "If your server has a proper DNS name and it public facing on the Internet with a public facing HTTP server on port 80, you can get a free TLS certificate.",
347 "type": "object",
348 "additionalProperties": false,
349 "properties": {
356 - "email": { "type": "string", "format": "email" },
350 + "email": { "type": "string", "format": "email", "description": "Email address of the administrator of this server. Make sure this is a valid email address otherwise the certificate request will fail." },
351 "names": { "type": "string" },
358 - "production": { "type": "boolean", "default": false }
352 + "production": { "type": "boolean", "default": false, "description": "By default a test certificate will be obtained from Let's Encrypt. Always start by getting a test certificate and make sure that works before setting this to true and obtaining a production certificaite. Making too many bad requests for a production certificate will get you banned for a long period of time." }
353 },
354 "required": [ "email", "names" ]
355 },
@@ -381,7 +375,7 @@
375 },
376 "smtp": {
377 "title" : "Email server",
384 - "description": "Connects MeshCentral to a email server, allows MeshCentral to send email messages for 2FA or user notification",
378 + "description": "Connects MeshCentral to a email server, allows MeshCentral to send email messages for 2FA or user notification.",
379 "type": "object",
380 "properties": {
381 "host": { "type": "string", "format": "hostname" },
@@ -395,18 +389,30 @@
389 },
390 "sms": {
391 "title" : "SMS provider",
398 - "description": "Connects MeshCentral to a SMS text messaging provider, allows MeshCentral to send SMS messages for 2FA or user notification",
399 - "type": "object",
400 - "properties": {
401 - "provider": { "type": "string", "enum": [ "twilio", "plivo" ] },
402 - "id": { "type": "string" },
403 - "sid": { "type": "string" },
404 - "token": { "type": "string" },
405 - "from": { "type": "string" }
406 - },
407 - "required": [ "provider", "token", "from" ]
392 + "description": "Connects MeshCentral to a SMS text messaging provider, allows MeshCentral to send SMS messages for 2FA or user notification.",
393 + "oneOf": [
394 + {
395 + "type": "object",
396 + "properties": {
397 + "provider": { "type": "string", "enum": [ "twilio" ] },
398 + "sid": { "type": "string" },
399 + "auth": { "type": "string" },
400 + "from": { "type": "string" }
401 + },
402 + "required": [ "provider", "sid", "auth", "from" ]
403 + },
404 + {
405 + "type": "object",
406 + "properties": {
407 + "provider": { "type": "string", "enum": [ "plivo" ] },
408 + "id": { "type": "string" },
409 + "token": { "type": "string" },
410 + "from": { "type": "string" }
411 + },
412 + "required": [ "provider", "id", "token", "from" ]
413 + }
414 + ]
415 }
416 },
417 "required": [ "settings", "domains" ]
418 }
412 -
sample-config-advanced.json
+127 -127
@@ -2,127 +2,127 @@
2 "$schema": "http://info.meshcentral.com/downloads/meshcentral-config-schema.json",
3 "__comment__": "This is a sample configuration file, all values and sections that start with underscore (_) are ignored. Edit a section and remove the _ in front of the name. Refer to the user's guide for details.",
4 "settings": {
5 - "_Cert": "myserver.mydomain.com",
6 - "_MongoDb": "mongodb://127.0.0.1:27017",
7 - "_MongoDbName": "meshcentral",
8 - "_MongoDbChangeStream": true,
9 - "_MongoDumpPath": "C:\\Program Files\\MongoDB\\Server\\4.2\\bin\\mongodump.exe",
5 + "_cert": "myserver.mydomain.com",
6 + "_mongoDb": "mongodb://127.0.0.1:27017",
7 + "_mongoDbName": "meshcentral",
8 + "_mongoDbChangeStream": true,
9 + "_mongoDumpPath": "C:\\Program Files\\MongoDB\\Server\\4.2\\bin\\mongodump.exe",
10 "_WANonly": true,
11 "_LANonly": true,
12 - "_SessionTime": 30,
13 - "_SessionKey": "MyReallySecretPassword1",
14 - "_SessionSameSite": "strict",
15 - "_DbEncryptKey": "MyReallySecretPassword2",
16 - "_DbRecordsEncryptKey": "MyReallySecretPassword",
17 - "_DbRecordsDecryptKey": "MyReallySecretPassword",
18 - "__DbExpire": "Amount of time to keep various events in the database, in seconds. Below are the default values.",
19 - "_DbExpire": {
12 + "_sessionTime": 30,
13 + "_sessionKey": "MyReallySecretPassword1",
14 + "_sessionSameSite": "strict",
15 + "_dbEncryptKey": "MyReallySecretPassword2",
16 + "_dbRecordsEncryptKey": "MyReallySecretPassword",
17 + "_dbRecordsDecryptKey": "MyReallySecretPassword",
18 + "__dbExpire": "Amount of time to keep various events in the database, in seconds. Below are the default values.",
19 + "_dbExpire": {
20 "events": 1728000,
21 "powerevents": 864000,
22 "statsevents": 2592000
23 },
24 - "_Port": 443,
25 - "_PortBind": "127.0.0.1",
26 - "_AliasPort": 444,
27 - "_RedirPort": 80,
28 - "_RedirPortBind": "127.0.0.1",
29 - "_RedirAliasPort": 80,
30 - "_AgentPort": 1234,
31 - "_AgentPortBind": "127.0.0.1",
32 - "_AgentAliasPort": 1234,
33 - "_AgentAliasDNS": "agents.myserver.mydomain.com",
34 - "_AgentPortTls": true,
35 - "_ExactPorts": true,
36 - "_AllowLoginToken": true,
37 - "_AllowFraming": true,
38 - "_CookieIpCheck": false,
39 - "_CookieEncoding": "hex",
40 - "_WebRTC": false,
41 - "_Nice404": false,
42 - "_ClickOnce": false,
43 - "_SelfUpdate": true,
44 - "_BrowserPing": 60,
45 - "_BrowserPong": 60,
46 - "_AgentPing": 60,
47 - "_AgentPong": 60,
48 - "_AgentIdleTimeout": 150,
49 - "_MeshErrorLogPath": "c:\\tmp",
50 - "_NpmPath": "c:\\npm.exe",
51 - "_NpmProxy": "http://1.2.3.4:80",
52 - "_AllowHighQualityDesktop": true,
53 - "_DesktopMultiplex": true,
54 - "_UserAllowedIP": "127.0.0.1,192.168.1.0/24",
55 - "_UserBlockedIP": "127.0.0.1,::1,192.168.0.100",
56 - "_AgentAllowedIP": "192.168.0.100/24",
57 - "_AgentBlockedIP": "127.0.0.1,::1",
58 - "_AuthLog": "c:\\temp\\auth.log",
59 - "_ManageAllDeviceGroups": [ "user//admin" ],
60 - "_ManageCrossDomain": [ "user//admin" ],
61 - "_LocalDiscovery": {
24 + "port": 443,
25 + "_portBind": "127.0.0.1",
26 + "aliasPort": 444,
27 + "_redirPort": 80,
28 + "_redirPortBind": "127.0.0.1",
29 + "_redirAliasPort": 80,
30 + "_agentPort": 1234,
31 + "_agentPortBind": "127.0.0.1",
32 + "_agentAliasPort": 1234,
33 + "_agentAliasDNS": "agents.myserver.mydomain.com",
34 + "_agentPortTls": true,
35 + "_exactPorts": true,
36 + "_allowLoginToken": true,
37 + "_allowFraming": true,
38 + "_cookieIpCheck": false,
39 + "_cookieEncoding": "hex",
40 + "_webRTC": false,
41 + "_nice404": false,
42 + "_clickOnce": false,
43 + "_selfUpdate": true,
44 + "_browserPing": 60,
45 + "_browserPong": 60,
46 + "_agentPing": 60,
47 + "_agentPong": 60,
48 + "_agentIdleTimeout": 150,
49 + "_meshErrorLogPath": "c:\\tmp",
50 + "_npmPath": "c:\\npm.exe",
51 + "_npmProxy": "http://1.2.3.4:80",
52 + "_allowHighQualityDesktop": true,
53 + "_desktopMultiplex": true,
54 + "_userAllowedIP": "127.0.0.1,192.168.1.0/24",
55 + "_userBlockedIP": "127.0.0.1,::1,192.168.0.100",
56 + "_agentAllowedIP": "192.168.0.100/24",
57 + "_agentBlockedIP": "127.0.0.1,::1",
58 + "_authLog": "c:\\temp\\auth.log",
59 + "_manageAllDeviceGroups": [ "user//admin" ],
60 + "_manageCrossDomain": [ "user//admin" ],
61 + "_localDiscovery": {
62 "name": "Local server name",
63 "info": "Information about this server"
64 },
65 - "_TlsOffload": "127.0.0.1,::1",
66 - "_TrustedProxy": "127.0.0.1,::1",
67 - "_MpsPort": 44330,
68 - "_MpsPortBind": "127.0.0.1",
69 - "_MpsAliasPort": 4433,
70 - "_MpsAliasHost": "mps.mydomain.com",
71 - "_MpsTlsOffload": true,
72 - "_No2FactorAuth": true,
73 - "_Log": "main,web,webrequest,cert",
65 + "_rlsOffload": "127.0.0.1,::1",
66 + "_rrustedProxy": "127.0.0.1,::1",
67 + "_mpsPort": 44330,
68 + "_mpsPortBind": "127.0.0.1",
69 + "_mpsAliasPort": 4433,
70 + "_mpsAliasHost": "mps.mydomain.com",
71 + "_mpsTlsOffload": true,
72 + "_no2FactorAuth": true,
73 + "_log": "main,web,webrequest,cert",
74 "_syslog": "meshcentral",
75 "_syslogauth": "meshcentral-auth",
76 "_syslogjson": "meshcentral-json",
77 - "_WebRtConfig": {
77 + "_webrtcConfig": {
78 "iceServers": [
79 { "urls": "stun:stun.services.mozilla.com" },
80 { "urls": "stun:stun.l.google.com:19302" }
81 ]
82 },
83 - "_AutoBackup": {
83 + "_autoBackup": {
84 "backupIntervalHours": 24,
85 "keepLastDaysBackup": 10,
86 "zipPassword": "MyReallySecretPassword3",
87 "_backupPath": "C:\\backups"
88 },
89 - "_Redirects": {
89 + "_redirects": {
90 "meshcommander": "https://www.meshcommander.com/"
91 },
92 - "__MaxInvalidLogin": "Time in minutes, max amount of bad logins from a source IP in the time before logins are rejected.",
93 - "_MaxInvalidLogin": {
92 + "__maxInvalidLogin": "Time in minutes, max amount of bad logins from a source IP in the time before logins are rejected.",
93 + "_maxInvalidLogin": {
94 "time": 10,
95 "count": 10,
96 "coolofftime": 10
97 },
98 - "_Plugins": { "enabled": true }
98 + "_plugins": { "enabled": true }
99 },
100 "_domaindefaults": {
101 "__comment__": "Any settings in this section is used as default setting for all domains",
102 - "Title": "MyDefaultTitle",
103 - "Footer": "Default page footer",
104 - "NewAccounts": false
102 + "title": "MyDefaultTitle",
103 + "footer": "Default page footer",
104 + "newAccounts": false
105 },
106 "_domains": {
107 "": {
108 - "Title": "MyServer",
109 - "Title2": "Servername",
110 - "_TitlePicture": "title-sample.png",
111 - "_UserQuota": 1048576,
112 - "_MeshQuota": 248576,
113 - "Minify": true,
114 - "_NewAccounts": true,
115 - "_NewAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
116 - "_UserNameIsEmail": true,
117 - "_NewAccountEmailDomains": [ "sample.com" ],
118 - "_NewAccountsRights": [ "nonewgroups", "notools" ],
119 - "_WelcomeText": "Sample Text on Login Page.",
120 - "_WelcomePicture": "mainwelcome.jpg",
121 - "___Hide__": "Sum of: 1 = Hide header, 2 = Hide tab, 4 = Hide footer, 8 = Hide title, 16 = Hide left bar",
122 - "_Hide": 4,
123 - "_Footer": "<a href='https://twitter.com/mytwitter'>Twitter</a>",
124 - "_CertUrl": "https://192.168.2.106:443/",
125 - "_PasswordRequirements": {
108 + "title": "MyServer",
109 + "title2": "Servername",
110 + "_titlePicture": "title-sample.png",
111 + "_userQuota": 1048576,
112 + "_meshQuota": 248576,
113 + "minify": true,
114 + "_newAccounts": true,
115 + "_newAccountsUserGroups": [ "ugrp//xxxxxxxxxxxxxxxxx" ],
116 + "_userNameIsEmail": true,
117 + "_newAccountEmailDomains": [ "sample.com" ],
118 + "_newAccountsRights": [ "nonewgroups", "notools" ],
119 + "_welcomeText": "Sample Text on Login Page.",
120 + "_welcomePicture": "mainwelcome.jpg",
121 + "___hide__": "Sum of: 1 = Hide header, 2 = Hide tab, 4 = Hide footer, 8 = Hide title, 16 = Hide left bar",
122 + "_hide": 4,
123 + "_footer": "<a href='https://twitter.com/mytwitter'>Twitter</a>",
124 + "_certUrl": "https://192.168.2.106:443/",
125 + "_passwordRequirements": {
126 "min": 8,
127 "max": 128,
128 "upper": 1,
@@ -133,41 +133,41 @@
133 "force2factor": true,
134 "skip2factor": "127.0.0.1,192.168.2.0/24"
135 },
136 - "_AgentInviteCodes": true,
137 - "_AgentNoProxy": true,
138 - "_GeoLocation": true,
136 + "_agentInviteCodes": true,
137 + "_agentNoProxy": true,
138 + "_geoLocation": true,
139 "_novnc": false,
140 "_mstsc": true,
141 "_consentMessages": {
142 - "Title": "MeshCentral",
143 - "Desktop": "{0} requesting remote desktop access. Grant access?",
144 - "Terminal": "{0} requesting remote terminal access. Grant access?",
145 - "Files": "{0} requesting remote files access. Grant access?"
142 + "title": "MeshCentral",
143 + "desktop": "{0} requesting remote desktop access. Grant access?",
144 + "terminal": "{0} requesting remote terminal access. Grant access?",
145 + "files": "{0} requesting remote files access. Grant access?"
146 },
147 "_notificationMessages": {
148 - "Title": "MeshCentral",
149 - "Desktop": "{0} started a remote desktop session.",
150 - "Terminal": "{0} started a remote terminal session.",
151 - "Files": "{0} started a remote files session."
148 + "title": "MeshCentral",
149 + "desktop": "{0} started a remote desktop session.",
150 + "terminal": "{0} started a remote terminal session.",
151 + "files": "{0} started a remote files session."
152 },
153 - "_UserAllowedIP": "127.0.0.1,192.168.1.0/24",
154 - "_UserBlockedIP": "127.0.0.1,::1,192.168.0.100",
155 - "_AgentAllowedIP": "192.168.0.100/24",
156 - "_AgentBlockedIP": "127.0.0.1,::1",
157 - "___UserSessionIdleTimeout__": "Number of user idle minutes before auto-disconnect",
158 - "_UserSessionIdleTimeout": 30,
159 - "__UserConsentFlags__": "Set to: 1 for desktop, 2 for terminal, 3 for files, 7 for all",
160 - "_UserConsentFlags": 7,
161 - "_UrlSwitching": false,
162 - "_DesktopPrivacyBarText": "Your privacy bar message",
163 - "_Limits": {
164 - "_MaxDevices": 100,
165 - "_MaxUserAccounts": 100,
166 - "_MaxUserSessions": 100,
167 - "_MaxAgentSessions": 100,
168 - "MaxSingleUserSessions": 10
153 + "_userAllowedIP": "127.0.0.1,192.168.1.0/24",
154 + "_userBlockedIP": "127.0.0.1,::1,192.168.0.100",
155 + "_agentAllowedIP": "192.168.0.100/24",
156 + "_agentBlockedIP": "127.0.0.1,::1",
157 + "___userSessionIdleTimeout__": "Number of user idle minutes before auto-disconnect",
158 + "_userSessionIdleTimeout": 30,
159 + "__userConsentFlags__": "Set to: 1 for desktop, 2 for terminal, 3 for files, 7 for all",
160 + "_userConsentFlags": 7,
161 + "_urlSwitching": false,
162 + "_desktopPrivacyBarText": "Your privacy bar message",
163 + "_limits": {
164 + "_maxDevices": 100,
165 + "_maxUserAccounts": 100,
166 + "_maxUserSessions": 100,
167 + "_maxAgentSessions": 100,
168 + "maxSingleUserSessions": 10
169 },
170 - "_AmtAcmActivation": {
170 + "_amtAcmActivation": {
171 "log": "amtactivation.log",
172 "certs": {
173 "mycertname": {
@@ -176,7 +176,7 @@
176 }
177 }
178 },
179 - "_Redirects": {
179 + "_redirects": {
180 "meshcommander": "https://www.meshcommander.com/"
181 },
182 "_yubikey": {
@@ -184,13 +184,13 @@
184 "secret": "xxxxxxxxxxxxxxxxxxxxx",
185 "_proxy": "http://myproxy.domain.com:80"
186 },
187 - "_httpheaders": {
187 + "_httpHeaders": {
188 "Strict-Transport-Security": "max-age=360000",
189 "x-frame-options": "SAMEORIGIN",
190 "Content-Security-Policy": "default-src 'none'; script-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; frame-src 'self'; media-src 'self'"
191 },
192 "_agentConfig": [ "webSocketMaskOverride=1" ],
193 - "_SessionRecording": {
193 + "_sessionRecording": {
194 "_filepath": "C:\\temp",
195 "_index": true,
196 "_maxRecordings": 10,
@@ -257,17 +257,17 @@
257 }
258 },
259 "_customer1": {
260 - "_DNS": "customer1.myserver.com",
261 - "_Title": "Customer1",
262 - "_Title2": "TestServer",
263 - "_NewAccounts": 1,
264 - "_Auth": "sspi",
265 - "__Auth": "ldap",
260 + "_dns": "customer1.myserver.com",
261 + "_title": "Customer1",
262 + "_title2": "TestServer",
263 + "_newAccounts": 1,
264 + "_auth": "sspi",
265 + "__auth": "ldap",
266 "_LDAPUserName": "gecos",
267 "_LDAPUserKey": "uid",
268 "_LDAPUserEmail": "otherMail",
269 "_LDAPPptions": {
270 - "URL": "test",
270 + "url": "test",
271 "anne": {
272 "gecos": "Anne O'Nyme",
273 "displayName": "O Nyme anne",
@@ -292,8 +292,8 @@
292 "SearchBase": "DC=meshcentral,DC=local",
293 "SearchFilter": "(sAMAccountName={{username}})"
294 },
295 - "_Footer": "Test",
296 - "_CertUrl": "https://192.168.2.106:443/"
295 + "_footer": "Test",
296 + "_certUrl": "https://192.168.2.106:443/"
297 },
298 "_info": {
299 "_share": "C:\\ExtraWebSite"
sample-config.json
+11 -11
@@ -3,22 +3,22 @@
3 "__comment1__": "This is a simple configuration file, all values and sections that start with underscore (_) are ignored. Edit a section and remove the _ in front of the name. Refer to the user's guide for details.",
4 "__comment2__": "See node_modules/meshcentral/sample-config-advanced.json for a more advanced example.",
5 "settings": {
6 - "_Cert": "myserver.mydomain.com",
6 + "_cert": "myserver.mydomain.com",
7 "_WANonly": true,
8 "_LANonly": true,
9 - "_SessionKey": "MyReallySecretPassword1",
10 - "_Port": 443,
11 - "_AliasPort": 443,
12 - "_RedirPort": 80,
13 - "_RedirAliasPort": 80
9 + "_sessionKey": "MyReallySecretPassword1",
10 + "_port": 443,
11 + "_aliasPort": 443,
12 + "_redirPort": 80,
13 + "_redirAliasPort": 80
14 },
15 "domains": {
16 "": {
17 - "_Title": "MyServer",
18 - "_Title2": "Servername",
19 - "_Minify": true,
20 - "_NewAccounts": true,
21 - "_UserNameIsEmail": true
17 + "_title": "MyServer",
18 + "_title2": "Servername",
19 + "_minify": true,
20 + "_newAccounts": true,
21 + "_userNameIsEmail": true
22 }
23 },
24 "_letsencrypt": {