From 6e1aef543dcf515e246cbd9c37d77ffbda2880b7 Mon Sep 17 00:00:00 2001 From: dgoodman-bw <109169446+dgoodman-bw@users.noreply.github.com> Date: Wed, 30 Nov 2022 15:47:19 -0700 Subject: [PATCH] Ps 1061 cli update command returns wrong version (#4071) * PS-1061 - replace out of date url references * PS-1061 - reverse position of error case handling to reduce nesting * PS-1061 - remove unnecessary constructor parameters, move downloadUrl construction to separate function * PS-1061 - move constants outside of class, readability improvements * PS-1061 - use standard notation for property assignment * PS-1061 - initialize downloadUrl with default value --- apps/cli/src/commands/update.command.ts | 177 ++++++++++++------------ apps/cli/src/program.ts | 8 +- 2 files changed, 92 insertions(+), 93 deletions(-) diff --git a/apps/cli/src/commands/update.command.ts b/apps/cli/src/commands/update.command.ts index b058feb72b..449afabbb5 100644 --- a/apps/cli/src/commands/update.command.ts +++ b/apps/cli/src/commands/update.command.ts @@ -1,104 +1,109 @@ import * as fetch from "node-fetch"; -import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service"; import { Response } from "../models/response"; import { MessageResponse } from "../models/response/message.response"; +const CLIENTS_RELEASE_LIST_ENDPOINT = "https://api.github.com/repos/bitwarden/clients/releases"; +const DEFAULT_DOWNLOAD_URL = "https://github.com/bitwarden/clients/releases"; +const UPDATE_COMMAND = "npm install -g @bitwarden/cli"; + export class UpdateCommand { inPkg = false; - constructor( - private platformUtilsService: PlatformUtilsService, - private i18nService: I18nService, - private repoName: string, - private executableName: string, - private showExtendedMessage: boolean - ) { + constructor(private platformUtilsService: PlatformUtilsService) { this.inPkg = !!(process as any).pkg; } async run(): Promise { - const currentVersion = await this.platformUtilsService.getApplicationVersion(); - - const response = await fetch.default( - "https://api.github.com/repos/bitwarden/" + this.repoName + "/releases/latest" - ); - if (response.status === 200) { - const responseJson = await response.json(); - const res = new MessageResponse(null, null); - - const tagName: string = responseJson.tag_name; - if (tagName === "v" + currentVersion) { - res.title = "No update available."; - res.noColor = true; - return Response.success(res); - } - - let downloadUrl: string = null; - if (responseJson.assets != null) { - for (const a of responseJson.assets) { - const download: string = a.browser_download_url; - if (download == null) { - continue; - } - - if (download.indexOf(".zip") === -1) { - continue; - } - - if ( - process.platform === "win32" && - download.indexOf(this.executableName + "-windows") > -1 - ) { - downloadUrl = download; - break; - } else if ( - process.platform === "darwin" && - download.indexOf(this.executableName + "-macos") > -1 - ) { - downloadUrl = download; - break; - } else if ( - process.platform === "linux" && - download.indexOf(this.executableName + "-linux") > -1 - ) { - downloadUrl = download; - break; - } - } - } - - res.title = "A new version is available: " + tagName; - if (downloadUrl == null) { - downloadUrl = "https://github.com/bitwarden/" + this.repoName + "/releases"; - } else { - res.raw = downloadUrl; - } - res.message = ""; - if (responseJson.body != null && responseJson.body !== "") { - res.message = responseJson.body + "\n\n"; - } - - res.message += "You can download this update at " + downloadUrl; - - if (this.showExtendedMessage) { - if (this.inPkg) { - res.message += - "\n\nIf you installed this CLI through a package manager " + - "you should probably update using its update command instead."; - } else { - res.message += - "\n\nIf you installed this CLI through NPM " + - "you should update using `npm install -g @bitwarden/" + - this.repoName + - "`"; - } - } - return Response.success(res); - } else { + const response = await fetch.default(CLIENTS_RELEASE_LIST_ENDPOINT); + if (response.status !== 200) { return Response.error("Error contacting update API: " + response.status); } + + const responseJson = await response.json(); + const cliRelease = responseJson.find((r: any) => r.tag_name.includes("cli")); + if (cliRelease === undefined || cliRelease === null) { + return Response.error("Could not find latest CLI version."); + } + + const currentVersion = await this.platformUtilsService.getApplicationVersion(); + if (cliRelease.tag_name === "cli-v" + currentVersion) { + const response = new MessageResponse(null, null); + response.title = "No update available."; + response.noColor = true; + return Response.success(response); + } + + const res = this.getFoundUpdateResponse(cliRelease); + return Response.success(res); + } + + private getFoundUpdateResponse(release: any) { + const downloadUrl = this.getDownloadUrl(release.assets); + + const response = new MessageResponse(null, null); + response.title = "A new version is available: " + release.tag_name; + response.raw = downloadUrl; + response.message = this.getMessage(release, downloadUrl); + + return response; + } + + private getMessage(release: any, downloadUrl: string) { + let message = ""; + + if (release.body != null && release.body !== "") { + message = release.body + "\n\n"; + } + + message += "You can download this update at " + downloadUrl; + + if (this.inPkg) { + message += + "\n\nIf you installed this CLI through a package manager " + + "you should probably update using its update command instead."; + } else { + message += + "\n\nIf you installed this CLI through NPM " + + "you should update using `" + + UPDATE_COMMAND + + "`"; + } + + return message; + } + + private getDownloadUrl(assets: any) { + if (assets == null) { + return DEFAULT_DOWNLOAD_URL; + } + + let downloadUrl: string = DEFAULT_DOWNLOAD_URL; + + for (const a of assets) { + const download: string = a.browser_download_url; + if (download == null) { + continue; + } + + if (download.indexOf(".zip") === -1) { + continue; + } + + if (process.platform === "win32" && download.indexOf("bw-windows") > -1) { + downloadUrl = download; + break; + } else if (process.platform === "darwin" && download.indexOf("bw-macos") > -1) { + downloadUrl = download; + break; + } else if (process.platform === "linux" && download.indexOf("bw-linux") > -1) { + downloadUrl = download; + break; + } + } + + return downloadUrl; } } diff --git a/apps/cli/src/program.ts b/apps/cli/src/program.ts index 41a99dcd9b..930d3f9344 100644 --- a/apps/cli/src/program.ts +++ b/apps/cli/src/program.ts @@ -403,13 +403,7 @@ export class Program { writeLn("", true); }) .action(async () => { - const command = new UpdateCommand( - this.main.platformUtilsService, - this.main.i18nService, - "cli", - "bw", - true - ); + const command = new UpdateCommand(this.main.platformUtilsService); const response = await command.run(); this.processResponse(response); });