@homebridge-plugins/homebridge-eufy-security 4.4.4-beta.9 → 4.4.4

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.
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const LIB_VERSION = "4.4.4-beta.9";
1
+ export const LIB_VERSION = "4.4.4";
2
2
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC"}
@@ -170,7 +170,7 @@ const App = {
170
170
  */
171
171
  _showAdminError() {
172
172
  this._root.innerHTML = `
173
- <div class="alert alert-danger alert-admin mt-4" role="alert">
173
+ <div class="alert alert-danger alert-admin" role="alert">
174
174
  <h5 class="alert-heading">${Helpers.iconHtml('warning.svg')} Admin Account Detected</h5>
175
175
  <p>
176
176
  You are not using a <strong>dedicated guest admin account</strong>.
@@ -404,6 +404,16 @@
404
404
  margin: 0px auto;
405
405
  }
406
406
 
407
+ .login-card .input-group {
408
+ overflow: visible;
409
+ }
410
+
411
+ .login-card .input-group > .eufy-tooltip::after {
412
+ left: auto;
413
+ right: 0;
414
+ transform: none;
415
+ }
416
+
407
417
  .login-section-title {
408
418
  font-size: 1.2rem;
409
419
  font-weight: 600;
@@ -537,6 +547,10 @@
537
547
  /* ===== Alert overrides ===== */
538
548
  .alert-admin {
539
549
  border-radius: var(--eufy-border-radius);
550
+ overflow-wrap: break-word;
551
+ word-break: break-word;
552
+ max-width: 100%;
553
+ box-sizing: border-box;
540
554
  }
541
555
 
542
556
  /* ===== Node.js Version Warning Banner ===== */
@@ -84,4 +84,32 @@ const Helpers = {
84
84
  const level = Math.max(0, Math.min(6, Math.round((pct / 100) * 6)));
85
85
  return 'battery_' + level + '.svg';
86
86
  },
87
+
88
+ /**
89
+ * Generate a random device name to identify this Homebridge instance to Eufy.
90
+ * @returns {string}
91
+ */
92
+ generateDeviceName() {
93
+ const _d = (s) => atob(s).split('|');
94
+ const _p = (a) => a[Math.floor(Math.random() * a.length)];
95
+ const style = Math.floor(Math.random() * 3);
96
+
97
+ if (style === 1) {
98
+ return _p(_d('Sm9obnxFbW1hfEphbWVzfE9saXZpYXxXaWxsaWFtfFNvcGhpYXxBbGV4fE1pYXxEYW5pZWx8RWxsYXxEYXZpZHxHcmFjZXxDaHJpc3xMaWx5fFNhbQ=='))
99
+ + '\'s '
100
+ + _p(_d('aVBob25lfGlQaG9uZSAxM3xpUGhvbmUgMTMgUHJvfGlQaG9uZSAxNHxpUGhvbmUgMTQgUHJvfGlQaG9uZSAxNXxpUGhvbmUgMTUgUHJvfGlQaG9uZSAxNSBQcm8gTWF4fGlQaG9uZSAxNnxpUGhvbmUgMTYgUHJvfGlQaG9uZSAxNiBQcm8gTWF4fGlQYWR8aVBhZCBBaXJ8aVBhZCBQcm8='));
101
+ }
102
+
103
+ if (style === 2) {
104
+ return _p(_d('Sm9obnxNYXJpYXxDYXJsb3N8U2FyYWh8QWxleHxQcml5YXxMZW98TmluYXxPbWFyfFphcmF8S2FpfFl1a2l8QmVufEF2YXxNYXg='))
105
+ + '\'s '
106
+ + _p(_d('R2FsYXh5IFMyM3xHYWxheHkgUzI0fEdhbGF4eSBTMjQgVWx0cmF8R2FsYXh5IEE1NHxHYWxheHkgWiBGbGlwNXxHYWxheHkgWiBGb2xkNXxQaXhlbCA3fFBpeGVsIDh8UGl4ZWwgOCBQcm98UGl4ZWwgOXxQaXhlbCA5IFByb3xPbmVQbHVzIDEyfEdhbGF4eSBUYWIgUzl8UGl4ZWwgVGFibGV0'));
107
+ }
108
+
109
+ return _p(_d('Q29yYWx8THVuYXJ8U29sYXJ8U3RlbGxhcnxBcmN0aWN8QW1iZXJ8QXp1cmV8Q3JpbXNvbnxHb2xkZW58SXZvcnl8SmFkZXxNYXBsZXxPbnl4fFBlYXJsfFF1YXJ0enxSdWJ5fFNpbHZlcnxUb3BhenxWZWx2ZXR8Q2VkYXI='))
110
+ + ' '
111
+ + _p(_d('QnJpZGdlfEh1YnxMaW5rfE5vZGV8R2F0ZXxSZWxheXxWYXVsdHxUb3dlcnxCZWFjb258TmV4dXN8UG9ydHxDb3JlfEFyY3xTcGFyaw=='))
112
+ + ' '
113
+ + Math.floor(Math.random() * 100);
114
+ },
87
115
  };
@@ -229,8 +229,13 @@ const LoginView = {
229
229
  </div>
230
230
  <div class="mb-3">
231
231
  <label for="login-device" class="form-label">Device Name</label>
232
- <input type="text" class="form-control" id="login-device" value="" placeholder="e.g. My Homebridge">
233
- <div class="form-text">A name to identify this Homebridge instance to Eufy. Can be left blank.</div>
232
+ <div class="input-group">
233
+ <input type="text" class="form-control" id="login-device" value="" placeholder="e.g. My Homebridge" required>
234
+ <button class="btn btn-outline-secondary eufy-tooltip" type="button" id="btn-generate-name" data-tooltip="Generate random name">
235
+ ${Helpers.iconHtml('refresh.svg', 16, 'Generate name')}
236
+ </button>
237
+ </div>
238
+ <div class="form-text">A name to identify this Homebridge instance to Eufy.</div>
234
239
  </div>
235
240
  <div id="login-error" class="alert alert-danger d-none" role="alert"></div>
236
241
  <button class="btn btn-primary w-100" id="btn-login" type="button">
@@ -252,6 +257,15 @@ const LoginView = {
252
257
  // Pre-fill from existing config if available
253
258
  this._prefillCredentials(body);
254
259
 
260
+ // Generate random device name (default if not already set by config)
261
+ const deviceInput = body.querySelector('#login-device');
262
+ if (!deviceInput.value) {
263
+ deviceInput.value = Helpers.generateDeviceName();
264
+ }
265
+ body.querySelector('#btn-generate-name').addEventListener('click', () => {
266
+ deviceInput.value = Helpers.generateDeviceName();
267
+ });
268
+
255
269
  // Submit
256
270
  body.querySelector('#btn-login').addEventListener('click', () => this._doLogin(body));
257
271
 
@@ -279,10 +293,10 @@ const LoginView = {
279
293
  const email = body.querySelector('#login-email').value.trim();
280
294
  const password = body.querySelector('#login-password').value;
281
295
  const country = body.querySelector('#login-country').value;
282
- const deviceName = body.querySelector('#login-device').value.trim() || '';
296
+ const deviceName = body.querySelector('#login-device').value.trim();
283
297
 
284
- if (!email || !password) {
285
- this._showError(body, 'Please enter your email and password.');
298
+ if (!email || !password || !deviceName) {
299
+ this._showError(body, 'Please enter your email, password, and device name.');
286
300
  return;
287
301
  }
288
302
 
@@ -320,6 +320,13 @@ class UiServer extends HomebridgePluginUiServer {
320
320
  try {
321
321
  if (options && options.username && options.password && !options.reconnect) {
322
322
  this.log.info('deleting persistent.json and accessories due to new login');
323
+ // Tear down any existing client so the new device name and credentials take effect
324
+ if (this.eufyClient) {
325
+ this.log.debug('Tearing down previous eufy client before fresh login');
326
+ this.eufyClient.removeAllListeners();
327
+ this.eufyClient.close();
328
+ this.eufyClient = null;
329
+ }
323
330
  await this.resetAccessoryData();
324
331
  await this.resetPersistentData();
325
332
  } else if (options && options.reconnect) {
@@ -350,7 +357,7 @@ class UiServer extends HomebridgePluginUiServer {
350
357
  this.config.username = options.username;
351
358
  this.config.password = options.password;
352
359
  this.config.country = country;
353
- this.config.trustedDeviceName = options.deviceName;
360
+ this.config.trustedDeviceName = (typeof options.deviceName === 'string' && options.deviceName.trim()) || this.config.trustedDeviceName;
354
361
  try {
355
362
  this.eufyClient = await EufySecurity.initialize(this.config, this.tsLog);
356
363
  this.eufyClient?.on('station added', this._onStationDiscovered.bind(this));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "displayName": "Homebridge Eufy Security",
3
3
  "name": "@homebridge-plugins/homebridge-eufy-security",
4
- "version": "4.4.4-beta.9",
4
+ "version": "4.4.4",
5
5
  "description": "Control Eufy Security from homebridge.",
6
6
  "type": "module",
7
7
  "license": "Apache-2.0",