diff --git a/package-lock.json b/package-lock.json index 4b27405d0..896436c59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -78,8 +78,8 @@ "@types/tar": "^6.1.10", "@types/tcp-port-used": "^1.0.4", "@types/unzipper": "^0.10.9", - "@typescript-eslint/eslint-plugin": "^6.12.0", - "@typescript-eslint/parser": "^6.12.0", + "@typescript-eslint/eslint-plugin": "^6.13.0", + "@typescript-eslint/parser": "^6.13.0", "babel-jest": "^29.7.0", "concurrently": "^8.2.2", "eslint": "^8.54.0", @@ -2722,16 +2722,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.12.0.tgz", - "integrity": "sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.13.0.tgz", + "integrity": "sha512-HTvbSd0JceI2GW5DHS3R9zbarOqjkM9XDR7zL8eCsBUO/eSiHcoNE7kSL5sjGXmVa9fjH5LCfHDXNnH4QLp7tQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/type-utils": "6.12.0", - "@typescript-eslint/utils": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", + "@typescript-eslint/scope-manager": "6.13.0", + "@typescript-eslint/type-utils": "6.13.0", + "@typescript-eslint/utils": "6.13.0", + "@typescript-eslint/visitor-keys": "6.13.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2757,15 +2757,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.12.0.tgz", - "integrity": "sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.13.0.tgz", + "integrity": "sha512-VpG+M7GNhHLI/aTDctqAV0XbzB16vf+qDX9DXuMZSe/0bahzDA9AKZB15NDbd+D9M4cDsJvfkbGOA7qiZ/bWJw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/typescript-estree": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", + "@typescript-eslint/scope-manager": "6.13.0", + "@typescript-eslint/types": "6.13.0", + "@typescript-eslint/typescript-estree": "6.13.0", + "@typescript-eslint/visitor-keys": "6.13.0", "debug": "^4.3.4" }, "engines": { @@ -2785,13 +2785,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.12.0.tgz", - "integrity": "sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.13.0.tgz", + "integrity": "sha512-2x0K2/CujsokIv+LN2T0l5FVDMtsCjkUyYtlcY4xxnxLAW+x41LXr16duoicHpGtLhmtN7kqvuFJ3zbz00Ikhw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0" + "@typescript-eslint/types": "6.13.0", + "@typescript-eslint/visitor-keys": "6.13.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2802,13 +2802,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.12.0.tgz", - "integrity": "sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.13.0.tgz", + "integrity": "sha512-YHufAmZd/yP2XdoD3YeFEjq+/Tl+myhzv+GJHSOz+ro/NFGS84mIIuLU3pVwUcauSmwlCrVXbBclkn1HfjY0qQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.12.0", - "@typescript-eslint/utils": "6.12.0", + "@typescript-eslint/typescript-estree": "6.13.0", + "@typescript-eslint/utils": "6.13.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2829,9 +2829,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.12.0.tgz", - "integrity": "sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.13.0.tgz", + "integrity": "sha512-oXg7DFxx/GmTrKXKKLSoR2rwiutOC7jCQ5nDH5p5VS6cmHE1TcPTaYQ0VPSSUvj7BnNqCgQ/NXcTBxn59pfPTQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2842,13 +2842,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.12.0.tgz", - "integrity": "sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.13.0.tgz", + "integrity": "sha512-IT4O/YKJDoiy/mPEDsfOfp+473A9GVqXlBKckfrAOuVbTqM8xbc0LuqyFCcgeFWpqu3WjQexolgqN2CuWBYbog==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/visitor-keys": "6.12.0", + "@typescript-eslint/types": "6.13.0", + "@typescript-eslint/visitor-keys": "6.13.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2869,17 +2869,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.12.0.tgz", - "integrity": "sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.13.0.tgz", + "integrity": "sha512-V+txaxARI8yznDkcQ6FNRXxG+T37qT3+2NsDTZ/nKLxv6VfGrRhTnuvxPUxpVuWWr+eVeIxU53PioOXbz8ratQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.12.0", - "@typescript-eslint/types": "6.12.0", - "@typescript-eslint/typescript-estree": "6.12.0", + "@typescript-eslint/scope-manager": "6.13.0", + "@typescript-eslint/types": "6.13.0", + "@typescript-eslint/typescript-estree": "6.13.0", "semver": "^7.5.4" }, "engines": { @@ -2894,12 +2894,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.12.0.tgz", - "integrity": "sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.13.0.tgz", + "integrity": "sha512-UQklteCEMCRoq/1UhKFZsHv5E4dN1wQSzJoxTfABasWk1HgJRdg1xNUve/Kv/Sdymt4x+iEzpESOqRFlQr/9Aw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.12.0", + "@typescript-eslint/types": "6.13.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -3897,9 +3897,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001564", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", - "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", "dev": true, "funding": [ { @@ -4752,9 +4752,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.594", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.594.tgz", - "integrity": "sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==", + "version": "1.4.595", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.595.tgz", + "integrity": "sha512-+ozvXuamBhDOKvMNUQvecxfbyICmIAwS4GpLmR0bsiSBlGnLaOcs2Cj7J8XSbW+YEaN3Xl3ffgpm+srTUWFwFQ==", "dev": true }, "node_modules/emittery": { diff --git a/package.json b/package.json index 5c81a8d27..61776b763 100644 --- a/package.json +++ b/package.json @@ -109,8 +109,8 @@ "@types/tar": "^6.1.10", "@types/tcp-port-used": "^1.0.4", "@types/unzipper": "^0.10.9", - "@typescript-eslint/eslint-plugin": "^6.12.0", - "@typescript-eslint/parser": "^6.12.0", + "@typescript-eslint/eslint-plugin": "^6.13.0", + "@typescript-eslint/parser": "^6.13.0", "babel-jest": "^29.7.0", "concurrently": "^8.2.2", "eslint": "^8.54.0", diff --git a/src/modules/plugins/plugins.service.ts b/src/modules/plugins/plugins.service.ts index db8c541db..a6c2a4849 100755 --- a/src/modules/plugins/plugins.service.ts +++ b/src/modules/plugins/plugins.service.ts @@ -79,6 +79,11 @@ export class PluginsService { // verified plugins cache private verifiedPlugins: string[] = []; + private verifiedPluginsIcons: { [key: string]: string } = {}; + private verifiedPluginsIconsPrefix = 'https://raw.githubusercontent.com/homebridge/verified/latest/'; + + private verifiedPluginsJson = 'https://raw.githubusercontent.com/homebridge/verified/latest/verified-plugins.json'; + private verifiedPluginsIconsJson = 'https://raw.githubusercontent.com/homebridge/verified/latest/plugin-icons.json'; // misc schemas private miscSchemas = { @@ -293,6 +298,9 @@ export class PluginsService { plugin.links = pkg.package.links; plugin.author = (pkg.package.publisher) ? pkg.package.publisher.username : null; plugin.verifiedPlugin = this.verifiedPlugins.includes(pkg.package.name); + plugin.icon = this.verifiedPluginsIcons[pkg.package.name] + ? `${this.verifiedPluginsIconsPrefix}${this.verifiedPluginsIcons[pkg.package.name]}` + : null; return plugin; }); @@ -349,6 +357,7 @@ export class PluginsService { description: (pkg.description) ? pkg.description.replace(/(?:https?|ftp):\/\/[\n\S]+/g, '').trim() : pkg.name, verifiedPlugin: this.verifiedPlugins.includes(pkg.name), + icon: this.verifiedPluginsIcons[pkg.name], } as HomebridgePlugin; // it's not installed; finish building the response @@ -363,6 +372,9 @@ export class PluginsService { }; plugin.author = (pkg.maintainers.length) ? pkg.maintainers[0].name : null; plugin.verifiedPlugin = this.verifiedPlugins.includes(pkg.name); + plugin.icon = this.verifiedPluginsIcons[pkg.name] + ? `${this.verifiedPluginsIconsPrefix}${this.verifiedPluginsIcons[pkg.name]}` + : null; return [plugin]; } catch (e) { @@ -1201,6 +1213,9 @@ export class PluginsService { description: (pjson.description) ? pjson.description.replace(/(?:https?|ftp):\/\/[\n\S]+/g, '').trim() : pjson.name, verifiedPlugin: this.verifiedPlugins.includes(pjson.name), + icon: this.verifiedPluginsIcons[pjson.name] + ? `${this.verifiedPluginsIconsPrefix}${this.verifiedPluginsIcons[pjson.name]}` + : null, installedVersion: installPath ? (pjson.version || '0.0.1') : null, globalInstall: (installPath !== this.configService.customPluginPath), settingsSchema: await pathExists(resolve(installPath, pjson.name, 'config.schema.json')) || this.miscSchemas[pjson.name], @@ -1474,7 +1489,13 @@ export class PluginsService { clearTimeout(this.verifiedPluginsRetryTimeout); try { this.verifiedPlugins = ( - await this.httpService.get('https://raw.githubusercontent.com/homebridge/verified/latest/verified-plugins.json', { + await this.httpService.get(this.verifiedPluginsJson, { + httpsAgent: null, + }).toPromise() + ).data; + + this.verifiedPluginsIcons = ( + await this.httpService.get(this.verifiedPluginsIconsJson, { httpsAgent: null, }).toPromise() ).data; diff --git a/src/modules/plugins/types.d.ts b/src/modules/plugins/types.d.ts index 3dc2874a1..f16ecb959 100644 --- a/src/modules/plugins/types.d.ts +++ b/src/modules/plugins/types.d.ts @@ -4,6 +4,7 @@ export interface HomebridgePlugin { displayName?: string; description?: string; verifiedPlugin?: boolean; + icon?: string; publicPackage?: boolean; installedVersion?: string; latestVersion?: string; diff --git a/ui/package-lock.json b/ui/package-lock.json index 503e3e785..a991bb938 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -4393,6 +4393,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead", "dev": true }, "node_modules/abbrev": { @@ -5377,9 +5378,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001564", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001564.tgz", - "integrity": "sha512-DqAOf+rhof+6GVx1y+xzbFPeOumfQnhYzVnZD6LAXijR77yPtm9mfOcqOnT3mpnJiZVT+kwLAFnRlZcIz+c6bg==", + "version": "1.0.30001565", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz", + "integrity": "sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w==", "funding": [ { "type": "opencollective", @@ -6607,9 +6608,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.594", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.594.tgz", - "integrity": "sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ==" + "version": "1.4.595", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.595.tgz", + "integrity": "sha512-+ozvXuamBhDOKvMNUQvecxfbyICmIAwS4GpLmR0bsiSBlGnLaOcs2Cj7J8XSbW+YEaN3Xl3ffgpm+srTUWFwFQ==" }, "node_modules/emoji-datasource": { "version": "15.0.1", diff --git a/ui/src/app/modules/plugins/plugin-card/plugin-card.component.ts b/ui/src/app/modules/plugins/plugin-card/plugin-card.component.ts index d67f90880..92e063b73 100644 --- a/ui/src/app/modules/plugins/plugin-card/plugin-card.component.ts +++ b/ui/src/app/modules/plugins/plugin-card/plugin-card.component.ts @@ -65,10 +65,9 @@ export class PluginCardComponent implements OnInit { } ngOnInit(): void { - this.plugin.icon = this.plugin.verifiedPlugin && this.plugin?.links?.homepage - ? `${this.plugin.links.homepage.split('#')[0]}/latest/branding/icon.png` - .replace('github.com', 'raw.githubusercontent.com') - : this.defaultIcon; + if (!this.plugin.icon) { + this.plugin.icon = this.defaultIcon; + } if ( this.plugin.installedVersion