smart-home-engine 0.19.9 → 0.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{m as O}from"./monaco-langs-BW2J83t5.js";import{t as I}from"./index-BMmVmcNK.js";/*!-----------------------------------------------------------------------------
1
+ import{m as O}from"./monaco-langs-BW2J83t5.js";import{t as I}from"./index-He-obaow.js";/*!-----------------------------------------------------------------------------
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
4
  * Released under the MIT license
@@ -155,10 +155,10 @@
155
155
  }
156
156
  })();
157
157
  </script>
158
- <script type="module" crossorigin src="/assets/index-BMmVmcNK.js"></script>
158
+ <script type="module" crossorigin src="/assets/index-He-obaow.js"></script>
159
159
  <link rel="modulepreload" crossorigin href="/assets/monaco-langs-BW2J83t5.js">
160
160
  <link rel="stylesheet" crossorigin href="/assets/monaco-langs-DyX1CsEw.css">
161
- <link rel="stylesheet" crossorigin href="/assets/index-ChpDowYT.css">
161
+ <link rel="stylesheet" crossorigin href="/assets/index-pFtY_ZRn.css">
162
162
  </head>
163
163
  <body>
164
164
  <div id="app"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smart-home-engine",
3
- "version": "0.19.9",
3
+ "version": "0.20.2",
4
4
  "description": "Node.js based script runner for use in MQTT based Smart Home environments",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -79,6 +79,7 @@ if (typeof config.port !== 'undefined') {
79
79
  auth: config.auth,
80
80
  password: config.password || null,
81
81
  proxyHeader: config.proxyHeader,
82
+ proxyLogoutUrl: config.proxyLogoutUrl || null,
82
83
  bindAddress: config.bindAddress,
83
84
  configPath: config.config,
84
85
  scriptDir: config.dir || null,
@@ -283,7 +284,13 @@ if (!config.url) {
283
284
  }
284
285
 
285
286
  if (config.url) {
286
- mqtt = modules.mqtt.connect(config.url, { will: { topic: config.name + '/connected', payload: '0', retain: true } });
287
+ const _mqttOpts = { will: { topic: config.name + '/connected', payload: '0', retain: true } };
288
+ if (config.mqttUsername) _mqttOpts.username = config.mqttUsername;
289
+ if (config.mqttPassword) _mqttOpts.password = config.mqttPassword;
290
+ if (config.mqttCa) _mqttOpts.ca = config.mqttCa;
291
+ if (config.mqttCert) _mqttOpts.cert = config.mqttCert;
292
+ if (config.mqttKey) _mqttOpts.key = config.mqttKey;
293
+ mqtt = modules.mqtt.connect(config.url, _mqttOpts);
287
294
  mqtt.publish(config.name + '/connected', '2', { retain: true });
288
295
 
289
296
  mqtt.on('connect', () => {
package/src/web/auth.js CHANGED
@@ -32,15 +32,17 @@ const _sessions = new Map(); // token (hex64) → { createdAt: number }
32
32
  let _mode = 'none';
33
33
  let _passwordHash = null; // bcrypt hash, only used in 'password' mode
34
34
  let _proxyHeader = 'x-remote-user'; // lowercase for req.headers lookup
35
+ let _proxyLogoutUrl = null; // URL to redirect to on logout in proxy mode
35
36
  let _configPath = null;
36
37
 
37
38
  /**
38
39
  * Initialise auth state. Called once from startServer().
39
40
  */
40
- function init({ auth = 'none', password = null, proxyHeader = 'X-Remote-User', configPath = null } = {}) {
41
+ function init({ auth = 'none', password = null, proxyHeader = 'X-Remote-User', proxyLogoutUrl = null, configPath = null } = {}) {
41
42
  _mode = auth;
42
43
  _passwordHash = password || null;
43
44
  _proxyHeader = proxyHeader.toLowerCase();
45
+ _proxyLogoutUrl = proxyLogoutUrl || null;
44
46
  _configPath = configPath;
45
47
  }
46
48
 
@@ -95,7 +97,9 @@ const router = express.Router();
95
97
 
96
98
  /** GET /she/auth/mode — always public */
97
99
  router.get('/mode', (req, res) => {
98
- res.json({ mode: _mode });
100
+ const r = { mode: _mode };
101
+ if (_mode === 'proxy' && _proxyLogoutUrl) r.proxyLogoutUrl = _proxyLogoutUrl;
102
+ res.json(r);
99
103
  });
100
104
 
101
105
  /** POST /she/auth/login — always public; only meaningful in password mode */
@@ -135,7 +139,7 @@ router.post('/setup', async (req, res) => {
135
139
  return res.status(401).json({ error: 'Unauthorized' });
136
140
  }
137
141
 
138
- const { mode, password, proxyHeader } = req.body || {};
142
+ const { mode, password, proxyHeader, proxyLogoutUrl } = req.body || {};
139
143
 
140
144
  if (!['none', 'password', 'proxy'].includes(mode)) {
141
145
  return res.status(400).json({ error: 'Invalid auth mode. Must be none, password, or proxy.' });
@@ -157,12 +161,14 @@ router.post('/setup', async (req, res) => {
157
161
  cfg.auth = mode;
158
162
  delete cfg.password;
159
163
  delete cfg.proxyHeader;
164
+ delete cfg.proxyLogoutUrl;
160
165
 
161
166
  if (mode === 'password') {
162
167
  cfg.password = await bcrypt.hash(password, BCRYPT_ROUNDS);
163
168
  }
164
169
  if (mode === 'proxy') {
165
170
  cfg.proxyHeader = proxyHeader || 'X-Remote-User';
171
+ if (proxyLogoutUrl) cfg.proxyLogoutUrl = proxyLogoutUrl;
166
172
  }
167
173
 
168
174
  // Write back
@@ -173,6 +179,7 @@ router.post('/setup', async (req, res) => {
173
179
  _mode = mode;
174
180
  _passwordHash = cfg.password || null;
175
181
  _proxyHeader = (cfg.proxyHeader || 'X-Remote-User').toLowerCase();
182
+ _proxyLogoutUrl = cfg.proxyLogoutUrl || null;
176
183
 
177
184
  // Invalidate all existing sessions when switching away from password mode
178
185
  if (mode !== 'password') _sessions.clear();
package/src/web/server.js CHANGED
@@ -72,7 +72,7 @@ app.post('/she/restart', (req, res) => {
72
72
  setTimeout(_systemdRestart, 200);
73
73
  });
74
74
 
75
- // npm version check — poll once on startup and every hour
75
+ // npm version check — poll once on startup and every 24 hours
76
76
  let _latestNpmVersion = null;
77
77
  async function _checkNpmVersion() {
78
78
  try {
@@ -82,7 +82,13 @@ async function _checkNpmVersion() {
82
82
  } catch { /* best-effort */ }
83
83
  }
84
84
  _checkNpmVersion();
85
- setInterval(_checkNpmVersion, 60 * 60 * 1000);
85
+ setInterval(_checkNpmVersion, 24 * 60 * 60 * 1000);
86
+
87
+ // Trigger an immediate version check (called by the UI refresh button)
88
+ app.post('/she/check-update', async (req, res) => {
89
+ await _checkNpmVersion();
90
+ res.json({ latestVersion: _latestNpmVersion });
91
+ });
86
92
 
87
93
  // Update — install latest npm package, then restart
88
94
  app.post('/she/update', (req, res) => {
@@ -190,7 +196,7 @@ let httpServer = null;
190
196
  /**
191
197
  * Start listening. Resolves with the actual port (useful when port 0 is given).
192
198
  * @param {number} port
193
- * @param {{ auth?: string, password?: string, proxyHeader?: string, bindAddress?: string, configPath?: string, scriptDir?: string }} [options]
199
+ * @param {{ auth?: string, password?: string, proxyHeader?: string, proxyLogoutUrl?: string, bindAddress?: string, configPath?: string, scriptDir?: string }} [options]
194
200
  * @returns {Promise<number>}
195
201
  */
196
202
  function startServer(port, options = {}) {
@@ -198,6 +204,7 @@ function startServer(port, options = {}) {
198
204
  auth: options.auth || 'none',
199
205
  password: options.password || null,
200
206
  proxyHeader: options.proxyHeader || 'X-Remote-User',
207
+ proxyLogoutUrl: options.proxyLogoutUrl || null,
201
208
  configPath: options.configPath || null,
202
209
  });
203
210
  if (options.configPath) {