From 135fb6b50695d733eb7a93c760e89ed9f186ba55 Mon Sep 17 00:00:00 2001
From: Northern Man <19808920+NorthernMan54@users.noreply.github.com>
Date: Tue, 14 Nov 2023 12:04:55 -0500
Subject: [PATCH 1/2] Fixes for npm not found #1698 (#1713)

---
 package-lock.json                             |  4 ++--
 package.json                                  |  4 ++--
 src/bin/hb-service.ts                         |  2 +-
 src/bin/platforms/linux.ts                    | 12 +++++++++--
 src/core/auth/auth.service.ts                 | 12 +++++++----
 src/core/spa/spa.filter.ts                    |  1 -
 .../accessories/accessories.gateway.ts        |  6 +++++-
 src/modules/backup/backup.controller.ts       |  6 +++++-
 src/modules/backup/backup.service.ts          | 12 +++++++++--
 .../config-editor/config-editor.service.ts    |  6 +++++-
 .../plugins-settings-ui.controller.ts         |  6 +++++-
 .../plugins-settings-ui.service.ts            |  6 +++++-
 src/modules/plugins/plugins.service.ts        | 18 ++++++++++++++---
 src/modules/server/server.controller.ts       |  1 -
 src/modules/server/server.module.ts           |  1 -
 src/modules/server/server.service.ts          | 20 +++++++++++--------
 .../setup-wizard/setup-wizard.controller.ts   | 12 +++++++++--
 17 files changed, 95 insertions(+), 34 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index c0c4eb062..6f9bd7889 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "homebridge-config-ui-x",
-  "version": "4.52.2",
+  "version": "4.52.3",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "homebridge-config-ui-x",
-      "version": "4.52.2",
+      "version": "4.52.3",
       "funding": [
         {
           "type": "github",
diff --git a/package.json b/package.json
index 636daf496..678a41bd9 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "homebridge-config-ui-x",
   "displayName": "Homebridge UI",
-  "version": "4.52.2",
+  "version": "4.52.3",
   "description": "A web based management, configuration and control platform for Homebridge.",
   "license": "MIT",
   "author": "oznu <dev@oz.nu>",
@@ -161,4 +161,4 @@
     "smart home",
     "hb-service"
   ]
-}
+}
\ No newline at end of file
diff --git a/src/bin/hb-service.ts b/src/bin/hb-service.ts
index b4c91e497..0953ce6b9 100644
--- a/src/bin/hb-service.ts
+++ b/src/bin/hb-service.ts
@@ -1221,7 +1221,7 @@ export class HomebridgeServiceHelper {
     const spinner = ora(`Installing Node.js ${targetVersion}`).start();
 
     try {
-      tar.x(extractConfig);
+      await tar.x(extractConfig);
       spinner.succeed(`Installed Node.js ${targetVersion}`);
     } catch (e) {
       spinner.fail(e.message);
diff --git a/src/bin/platforms/linux.ts b/src/bin/platforms/linux.ts
index adec8d6b8..33e30ef5f 100644
--- a/src/bin/platforms/linux.ts
+++ b/src/bin/platforms/linux.ts
@@ -616,12 +616,20 @@ export class LinuxInstaller extends BasePlatform {
   private async createFirewallRules() {
     // check ufw is present on the system (debian based linux)
     if (await fs.pathExists('/usr/sbin/ufw')) {
-      return this.createUfwRules();
+      try {
+        return await this.createUfwRules();
+      } catch (err) {
+        throw err;
+      }
     }
 
     // check firewall-cmd is present on the system (enterprise linux)
     if (await fs.pathExists('/usr/bin/firewall-cmd')) {
-      return this.createFirewallCmdRules();
+      try {
+        return await this.createFirewallCmdRules();
+      } catch (err) {
+        throw err;
+      }
     }
   }
 
diff --git a/src/core/auth/auth.service.ts b/src/core/auth/auth.service.ts
index 83d34de51..d987d92c6 100644
--- a/src/core/auth/auth.service.ts
+++ b/src/core/auth/auth.service.ts
@@ -91,7 +91,7 @@ export class AuthService {
    */
   async signIn(username: string, password: string, otp?: string): Promise<any> {
     const user = await this.authenticate(username, password, otp);
-    const token = this.jwtService.sign(user);
+    const token = await this.jwtService.sign(user);
 
     return {
       access_token: token,
@@ -130,7 +130,7 @@ export class AuthService {
     const user = users.find(x => x.admin === true);
 
     // generate a token
-    const token = this.jwtService.sign({
+    const token = await this.jwtService.sign({
       username: user.username,
       name: user.name,
       admin: user.admin,
@@ -226,7 +226,7 @@ export class AuthService {
     }
 
     // generate a token
-    const token = this.jwtService.sign({
+    const token = await this.jwtService.sign({
       username: 'setup-wizard',
       name: 'setup-wizard',
       admin: true,
@@ -310,7 +310,11 @@ export class AuthService {
    */
   private async saveUserFile(users: UserDto[]) {
     // update the auth.json
-    return fs.writeJson(this.configService.authPath, users, { spaces: 4 });
+    try {
+      return await fs.writeJson(this.configService.authPath, users, { spaces: 4 });
+    } catch (err) {
+      throw err;
+    }
   }
 
   /**
diff --git a/src/core/spa/spa.filter.ts b/src/core/spa/spa.filter.ts
index aafd7a887..245076a25 100644
--- a/src/core/spa/spa.filter.ts
+++ b/src/core/spa/spa.filter.ts
@@ -8,7 +8,6 @@ import {
 } from '@nestjs/common';
 import * as fs from 'fs-extra';
 
-
 @Catch(NotFoundException)
 export class SpaFilter implements ExceptionFilter {
   catch(_exception: HttpException, host: ArgumentsHost) {
diff --git a/src/modules/accessories/accessories.gateway.ts b/src/modules/accessories/accessories.gateway.ts
index eb1434515..b9b54fe47 100644
--- a/src/modules/accessories/accessories.gateway.ts
+++ b/src/modules/accessories/accessories.gateway.ts
@@ -22,7 +22,11 @@ export class AccessoriesGateway {
 
   @SubscribeMessage('get-layout')
   async getAccessoryLayout(client: any, payload: any) {
-    return this.accessoriesService.getAccessoryLayout(payload.user);
+    try {
+      return await this.accessoriesService.getAccessoryLayout(payload.user);
+    } catch (err) {
+      throw err;
+    }
   }
 
   @SubscribeMessage('save-layout')
diff --git a/src/modules/backup/backup.controller.ts b/src/modules/backup/backup.controller.ts
index 5c0db441c..aaad9d583 100644
--- a/src/modules/backup/backup.controller.ts
+++ b/src/modules/backup/backup.controller.ts
@@ -105,7 +105,11 @@ export class BackupController {
     description: 'Logs to stdout / stderr.',
   })
   async restoreBackupTrigger() {
-    return this.backupService.triggerHeadlessRestore();
+    try {
+      return await this.backupService.triggerHeadlessRestore();
+    } catch (err) {
+      throw err;
+    }
   }
 
   @UseGuards(AdminGuard)
diff --git a/src/modules/backup/backup.service.ts b/src/modules/backup/backup.service.ts
index b0c3165ce..2840b23dd 100644
--- a/src/modules/backup/backup.service.ts
+++ b/src/modules/backup/backup.service.ts
@@ -175,7 +175,11 @@ export class BackupService {
       }
     } else {
       // when not using a custom backup path, just ensure it exists
-      return fs.ensureDir(this.configService.instanceBackupPath);
+      try {
+        return await fs.ensureDir(this.configService.instanceBackupPath);
+      } catch (err) {
+        throw err;
+      }
     }
   }
 
@@ -337,7 +341,11 @@ export class BackupService {
    */
   async removeRestoreDirectory() {
     if (this.restoreDirectory) {
-      return fs.remove(this.restoreDirectory);
+      try {
+        return await fs.remove(this.restoreDirectory);
+      } catch (err) {
+        throw err;
+      }
     }
   }
 
diff --git a/src/modules/config-editor/config-editor.service.ts b/src/modules/config-editor/config-editor.service.ts
index 7d7cde54d..e32616d5e 100644
--- a/src/modules/config-editor/config-editor.service.ts
+++ b/src/modules/config-editor/config-editor.service.ts
@@ -333,7 +333,11 @@ export class ConfigEditorService {
     }
 
     // read source backup
-    return fs.readFile(requestedBackupPath);
+    try {
+      return await fs.readFile(requestedBackupPath);
+    } catch (err) {
+      throw err;
+    }
   }
 
   /**
diff --git a/src/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.controller.ts b/src/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.controller.ts
index acf611589..36668064f 100644
--- a/src/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.controller.ts
+++ b/src/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.controller.ts
@@ -20,7 +20,11 @@ export class PluginsSettingsUiController {
   @ApiOperation({ summary: 'Returns the HTML assets for a plugin\'s custom UI' })
   @ApiParam({ name: 'pluginName', type: 'string' })
   async serveCustomUiAsset(@Res() reply, @Param('pluginName') pluginName, @Param('*') file, @Query('origin') origin: string, @Query('v') v?: string) {
-    return this.pluginSettingsUiService.serveCustomUiAsset(reply, pluginName, file, origin, v);
+    try {
+      return await this.pluginSettingsUiService.serveCustomUiAsset(reply, pluginName, file, origin, v);
+    } catch (err) {
+      throw err;
+    }
   }
 
 }
diff --git a/src/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.ts b/src/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.ts
index e32e4e36e..d40266e9e 100644
--- a/src/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.ts
+++ b/src/modules/custom-plugins/plugins-settings-ui/plugins-settings-ui.service.ts
@@ -117,7 +117,11 @@ export class PluginsSettingsUiService {
       // dev server is only enabled for private plugins
       return (await this.httpService.get(pluginUi.devServer, { responseType: 'text' }).toPromise()).data;
     } else {
-      return fs.readFile(path.join(pluginUi.publicPath, 'index.html'), 'utf8');
+      try {
+        return await fs.readFile(path.join(pluginUi.publicPath, 'index.html'), 'utf8');
+      } catch (err) {
+        throw err;
+      }
     }
   }
 
diff --git a/src/modules/plugins/plugins.service.ts b/src/modules/plugins/plugins.service.ts
index 2272cd617..2d25d7879 100755
--- a/src/modules/plugins/plugins.service.ts
+++ b/src/modules/plugins/plugins.service.ts
@@ -266,7 +266,11 @@ export class PluginsService {
       && (query.indexOf('homebridge-') === 0 || this.isScopedPlugin(query))
       && !this.searchResultBlacklist.includes(query.toLowerCase())
     ) {
-      return this.searchNpmRegistrySingle(query.toLowerCase());
+      try {
+        return await this.searchNpmRegistrySingle(query.toLowerCase());
+      } catch (err) {
+        throw err;
+      }
     }
 
     return _.orderBy(result, ['verifiedPlugin'], ['desc']);
@@ -455,7 +459,11 @@ export class PluginsService {
     if (this.configService.ui.homebridgePackagePath) {
       const pjsonPath = path.join(this.configService.ui.homebridgePackagePath, 'package.json');
       if (await fs.pathExists(pjsonPath)) {
-        return this.parsePackageJson(await fs.readJson(pjsonPath), this.configService.ui.homebridgePackagePath);
+        try {
+          return await this.parsePackageJson(await fs.readJson(pjsonPath), this.configService.ui.homebridgePackagePath);
+        } catch (err) {
+          throw err;
+        }
       } else {
         this.logger.error(`"homebridgePath" (${this.configService.ui.homebridgePackagePath}) does not exist`);
       }
@@ -724,7 +732,11 @@ export class PluginsService {
     const schemaPath = path.resolve(plugin.installPath, pluginName, 'config.schema.json');
 
     if (this.miscSchemas[pluginName] && !await fs.pathExists(schemaPath)) {
-      return fs.readJson(this.miscSchemas[pluginName]);
+      try {
+        return await fs.readJson(this.miscSchemas[pluginName]);
+      } catch (err) {
+        throw err;
+      }
     }
 
     let configSchema = await fs.readJson(schemaPath);
diff --git a/src/modules/server/server.controller.ts b/src/modules/server/server.controller.ts
index c3fe7c271..13586dc01 100644
--- a/src/modules/server/server.controller.ts
+++ b/src/modules/server/server.controller.ts
@@ -171,4 +171,3 @@ export class ServerController {
     return this.serverService.setHomebridgeMdnsSetting(body);
   }
 }
-
diff --git a/src/modules/server/server.module.ts b/src/modules/server/server.module.ts
index b7ea59b64..155d5491f 100644
--- a/src/modules/server/server.module.ts
+++ b/src/modules/server/server.module.ts
@@ -30,4 +30,3 @@ import { ServerService } from './server.service';
   ]
 })
 export class ServerModule { }
-
diff --git a/src/modules/server/server.service.ts b/src/modules/server/server.service.ts
index 965b0816a..434f41601 100644
--- a/src/modules/server/server.service.ts
+++ b/src/modules/server/server.service.ts
@@ -7,18 +7,18 @@ import {
   NotFoundException,
   ServiceUnavailableException
 } from '@nestjs/common';
-import {Categories} from '@oznu/hap-client/dist/hap-types';
+import { Categories } from '@oznu/hap-client/dist/hap-types';
 import * as bufferShim from 'buffer-shims';
 import * as fs from 'fs-extra';
 import * as NodeCache from 'node-cache';
 import * as si from 'systeminformation';
 import * as tcpPortUsed from 'tcp-port-used';
-import {ConfigService, HomebridgeConfig} from '../../core/config/config.service';
-import {HomebridgeIpcService} from '../../core/homebridge-ipc/homebridge-ipc.service';
-import {Logger} from '../../core/logger/logger.service';
-import {AccessoriesService} from '../accessories/accessories.service';
-import {ConfigEditorService} from '../config-editor/config-editor.service';
-import {HomebridgeMdnsSettingDto} from './server.dto';
+import { ConfigService, HomebridgeConfig } from '../../core/config/config.service';
+import { HomebridgeIpcService } from '../../core/homebridge-ipc/homebridge-ipc.service';
+import { Logger } from '../../core/logger/logger.service';
+import { AccessoriesService } from '../accessories/accessories.service';
+import { ConfigEditorService } from '../config-editor/config-editor.service';
+import { HomebridgeMdnsSettingDto } from './server.dto';
 
 @Injectable()
 export class ServerService {
@@ -108,7 +108,11 @@ export class ServerService {
       .filter(x => x.match(/AccessoryInfo\.([A-F,a-f0-9]+)\.json/));
 
     return Promise.all(devices.map(async (x) => {
-      return this.getDevicePairingById(x.split('.')[1]);
+      try {
+        return await this.getDevicePairingById(x.split('.')[1]);
+      } catch (err) {
+        throw err;
+      }
     }));
   }
 
diff --git a/src/modules/setup-wizard/setup-wizard.controller.ts b/src/modules/setup-wizard/setup-wizard.controller.ts
index af49162b5..e87a84af6 100644
--- a/src/modules/setup-wizard/setup-wizard.controller.ts
+++ b/src/modules/setup-wizard/setup-wizard.controller.ts
@@ -24,7 +24,11 @@ export class SetupWizardController {
     description: 'This endpoint is not available after the Homebridge setup wizard is complete.',
   })
   async setupFirstUser(@Body() body: UserDto) {
-    return this.authService.setupFirstUser(body);
+    try {
+      return await this.authService.setupFirstUser(body);
+    } catch (err) {
+      throw err;
+    }
   }
 
   @Get('/get-setup-wizard-token')
@@ -33,6 +37,10 @@ export class SetupWizardController {
     description: 'This endpoint is not available after the Homebridge setup wizard is complete.',
   })
   async generateSetupWizardToken() {
-    return this.authService.generateSetupWizardToken();
+    try {
+      return await this.authService.generateSetupWizardToken();
+    } catch (err) {
+      throw err;
+    }
   }
 }

From bd78cff84ec48b2bac3da9ed6bea805831c167a8 Mon Sep 17 00:00:00 2001
From: Northern Man <19808920+NorthernMan54@users.noreply.github.com>
Date: Tue, 14 Nov 2023 12:26:11 -0500
Subject: [PATCH 2/2] Promote 4.52.3 (#1714)

Co-authored-by: Donavan Becker <beckersmarthome@icloud.com>
---
 CHANGELOG.md         |  6 ++++++
 ui/package-lock.json | 28 ++++++++++++++--------------
 ui/package.json      |  8 ++++----
 3 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 13306a9e3..7f809f684 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
 
 All notable changes to homebridge-config-ui-x will be documented in this file.
 
+## 4.52.3 (2023-11-14)
+
+### Bug Fixes
+
+- Fixes for #1698, update-node failing with npm not found
+
 ## 4.52.2 (2023-11-11)
 
 ### Notable Changes
diff --git a/ui/package-lock.json b/ui/package-lock.json
index 32bc42d15..d3073964a 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -49,9 +49,9 @@
         "semver": "7.5.4",
         "socket.io-client": "2.5.0",
         "tslib": "2.6.2",
-        "xterm": "5.3.0",
-        "xterm-addon-fit": "0.8.0",
-        "xterm-addon-web-links": "0.9.0",
+        "xterm": "4.19.0",
+        "xterm-addon-fit": "0.5.0",
+        "xterm-addon-web-links": "0.6.0",
         "zone.js": "0.12.0"
       },
       "devDependencies": {
@@ -15214,24 +15214,24 @@
       }
     },
     "node_modules/xterm": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/xterm/-/xterm-5.3.0.tgz",
-      "integrity": "sha512-8QqjlekLUFTrU6x7xck1MsPzPA571K5zNqWm0M0oroYEWVOptZ0+ubQSkQ3uxIEhcIHRujJy6emDWX4A7qyFzg=="
+      "version": "4.19.0",
+      "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.19.0.tgz",
+      "integrity": "sha512-c3Cp4eOVsYY5Q839dR5IejghRPpxciGmLWWaP9g+ppfMeBChMeLa1DCA+pmX/jyDZ+zxFOmlJL/82qVdayVoGQ=="
     },
     "node_modules/xterm-addon-fit": {
-      "version": "0.8.0",
-      "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.8.0.tgz",
-      "integrity": "sha512-yj3Np7XlvxxhYF/EJ7p3KHaMt6OdwQ+HDu573Vx1lRXsVxOcnVJs51RgjZOouIZOczTsskaS+CpXspK81/DLqw==",
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz",
+      "integrity": "sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==",
       "peerDependencies": {
-        "xterm": "^5.0.0"
+        "xterm": "^4.0.0"
       }
     },
     "node_modules/xterm-addon-web-links": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/xterm-addon-web-links/-/xterm-addon-web-links-0.9.0.tgz",
-      "integrity": "sha512-LIzi4jBbPlrKMZF3ihoyqayWyTXAwGfu4yprz1aK2p71e9UKXN6RRzVONR0L+Zd+Ik5tPVI9bwp9e8fDTQh49Q==",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/xterm-addon-web-links/-/xterm-addon-web-links-0.6.0.tgz",
+      "integrity": "sha512-H6XzjWWZu8FBo+fnYpxdPk9w5M6drbsvwPEJZGRS38MihiQaVFpKlCMKdfRgDbKGE530tw1yH54rhpZfHgt2/A==",
       "peerDependencies": {
-        "xterm": "^5.0.0"
+        "xterm": "^4.0.0"
       }
     },
     "node_modules/y18n": {
diff --git a/ui/package.json b/ui/package.json
index ef080dffb..df025d28c 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -51,9 +51,9 @@
     "semver": "7.5.4",
     "socket.io-client": "2.5.0",
     "tslib": "2.6.2",
-    "xterm": "5.3.0",
-    "xterm-addon-fit": "0.8.0",
-    "xterm-addon-web-links": "0.9.0",
+    "xterm": "4.19.0",
+    "xterm-addon-fit": "0.5.0",
+    "xterm-addon-web-links": "0.6.0",
     "zone.js": "0.12.0"
   },
   "devDependencies": {
@@ -91,4 +91,4 @@
     "marked": "^5.1.2",
     "rxjs": "7.8.1"
   }
-}
+}
\ No newline at end of file