diff --git a/package.json b/package.json index c3a7d2e0..9ef27de0 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "dependencies": { "@oclif/core": "^3.15.0", "@salesforce/core": "^6.4.2", - "@salesforce/sf-plugins-core": "^5.0.13", + "@salesforce/sf-plugins-core": "^7.0.0", "got": "^13.0.0", "npm": "10.2.3", "npm-run-path": "^4.0.1", diff --git a/src/shared/installationVerification.ts b/src/shared/installationVerification.ts index 336be975..77d1c710 100644 --- a/src/shared/installationVerification.ts +++ b/src/shared/installationVerification.ts @@ -12,19 +12,19 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import { mkdir } from 'node:fs/promises'; - import { Logger, SfError, Messages } from '@salesforce/core'; import got from 'got'; import { ProxyAgent } from 'proxy-agent'; -import { Prompter } from '@salesforce/sf-plugins-core'; import { ux } from '@oclif/core'; +import { prompts } from '@salesforce/sf-plugins-core'; import { NpmModule, NpmMeta } from './npmCommand.js'; import { NpmName } from './NpmName.js'; import { setErrorName } from './errors.js'; + const CRYPTO_LEVEL = 'RSA-SHA256'; const ALLOW_LIST_FILENAME = 'unsignedPluginAllowList.json'; export const DEFAULT_REGISTRY = 'https://registry.npmjs.org/'; -Messages.importMessagesDirectoryFromMetaUrl(import.meta.url) +Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); export interface ConfigContext { configDir?: string; @@ -434,7 +434,7 @@ export class VerificationConfig { export async function doPrompt(): Promise { const messages = Messages.loadMessages('@salesforce/plugin-trust', 'verify'); - if (!(await new Prompter().confirm(messages.getMessage('InstallConfirmation'), 30000, false))) { + if (!(await prompts.confirm({ message: messages.getMessage('InstallConfirmation'), ms: 30_000 }))) { throw new SfError('The user canceled the plugin installation.', 'InstallationCanceledError'); } // they approved the plugin. Let them know how to automate this. diff --git a/test/hooks/verifyInstallSignatureHook.test.ts b/test/hooks/verifyInstallSignatureHook.test.ts index 7b943d61..1b80e1e5 100644 --- a/test/hooks/verifyInstallSignatureHook.test.ts +++ b/test/hooks/verifyInstallSignatureHook.test.ts @@ -9,7 +9,7 @@ import sinon from 'sinon'; import { stubMethod } from '@salesforce/ts-sinon'; -import { Prompter } from '@salesforce/sf-plugins-core'; +import { prompts } from '@salesforce/sf-plugins-core'; import { InstallationVerification, VerificationConfig } from '../../src/shared/installationVerification.js'; import { hook } from '../../src/hooks/verifyInstallSignature.js'; @@ -33,7 +33,7 @@ describe('plugin install hook', () => { }); stubMethod(sandbox, vConfig.verifier, 'isAllowListed').callsFake(async () => false); - promptSpy = stubMethod(sandbox, Prompter.prototype, 'confirm').resolves(false); + promptSpy = stubMethod(sandbox, prompts, 'confirm').resolves(false); }); afterEach(() => { diff --git a/test/nuts/plugin-install.nut.ts b/test/nuts/plugin-install.nut.ts index 36478f70..728ae4ab 100644 --- a/test/nuts/plugin-install.nut.ts +++ b/test/nuts/plugin-install.nut.ts @@ -72,7 +72,9 @@ describe('plugins:install commands', () => { } ); - expect(result.stdout.replaceAll('\n', '')).to.contain(messages.getMessage('InstallConfirmation')); + expect(replaceAllWhitespace(result.stdout)).to.contain( + replaceAllWhitespace(messages.getMessage('InstallConfirmation')) + ); expect(result.stdout).to.contain('Do you want to continue the installation?'); expect(result.stderr).to.contain('The user canceled the plugin installation'); }); @@ -86,7 +88,9 @@ describe('plugins:install commands', () => { cli: 'sf', } ); - expect(result.stdout.replaceAll('\n', '')).to.contain(messages.getMessage('InstallConfirmation')); + expect(replaceAllWhitespace(result.stdout)).to.contain( + replaceAllWhitespace(messages.getMessage('InstallConfirmation')) + ); expect(result.stdout).to.contain('Do you want to continue the installation?'); expect(result.stdout).to.contain('Finished digital signature check'); }); @@ -103,3 +107,5 @@ describe('plugins:install commands', () => { expect(result.shellOutput.stdout).to.contain(messages.getMessage('SkipSignatureCheck', [UNSIGNED_MODULE_NAME2])); }); }); + +const replaceAllWhitespace = (str: string): string => str.replaceAll('\n', '').replaceAll(' ', ''); diff --git a/test/shared/installationVerification.test.ts b/test/shared/installationVerification.test.ts index aea5942a..2a1c7f6f 100644 --- a/test/shared/installationVerification.test.ts +++ b/test/shared/installationVerification.test.ts @@ -14,7 +14,7 @@ import { OptionsOfTextResponseBody } from 'got'; import shelljs from 'shelljs'; import { stubMethod } from '@salesforce/ts-sinon'; import { SfError } from '@salesforce/core'; -import { Prompter } from '@salesforce/sf-plugins-core'; +import { prompts } from '@salesforce/sf-plugins-core'; import Sinon from 'sinon'; import { ConfigContext, @@ -634,7 +634,7 @@ describe('InstallationVerification Tests', () => { }, } as Verifier; - stubMethod(sandbox, Prompter.prototype, 'confirm').resolves(false); + stubMethod(sandbox, prompts, 'confirm').resolves(false); try { await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig); @@ -657,7 +657,7 @@ describe('InstallationVerification Tests', () => { }, } as Verifier; - stubMethod(sandbox, Prompter.prototype, 'confirm').resolves(true); + stubMethod(sandbox, prompts, 'confirm').resolves(true); try { await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig); @@ -680,7 +680,7 @@ describe('InstallationVerification Tests', () => { }, } as Verifier; - stubMethod(sandbox, Prompter.prototype, 'confirm').resolves(true); + stubMethod(sandbox, prompts, 'confirm').resolves(true); try { await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig); @@ -705,7 +705,7 @@ describe('InstallationVerification Tests', () => { }, } as Verifier; - stubMethod(sandbox, Prompter.prototype, 'confirm').resolves(true); + stubMethod(sandbox, prompts, 'confirm').resolves(true); try { await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig); @@ -730,7 +730,7 @@ describe('InstallationVerification Tests', () => { }, } as Verifier; - stubMethod(sandbox, Prompter.prototype, 'confirm').resolves(true); + stubMethod(sandbox, prompts, 'confirm').resolves(true); try { await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig); diff --git a/yarn.lock b/yarn.lock index 62b94c37..2c8c59ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -521,6 +521,59 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== +"@inquirer/confirm@^2.0.15": + version "2.0.15" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-2.0.15.tgz#b5512ed190efd8c5b96e0969115756b48546ab36" + integrity sha512-hj8Q/z7sQXsF0DSpLQZVDhWYGN6KLM/gNjjqGkpKwBzljbQofGjn0ueHADy4HUY+OqDHmXuwk/bY+tZyIuuB0w== + dependencies: + "@inquirer/core" "^5.1.1" + "@inquirer/type" "^1.1.5" + chalk "^4.1.2" + +"@inquirer/core@^5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-5.1.1.tgz#849d4846aea68371c133df6ec9059f5e5bd30d30" + integrity sha512-IuJyZQUg75+L5AmopgnzxYrgcU6PJKL0hoIs332G1Gv55CnmZrhG6BzNOeZ5sOsTi1YCGOopw4rYICv74ejMFg== + dependencies: + "@inquirer/type" "^1.1.5" + "@types/mute-stream" "^0.0.4" + "@types/node" "^20.9.0" + "@types/wrap-ansi" "^3.0.0" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + cli-spinners "^2.9.1" + cli-width "^4.1.0" + figures "^3.2.0" + mute-stream "^1.0.0" + run-async "^3.0.0" + signal-exit "^4.1.0" + strip-ansi "^6.0.1" + wrap-ansi "^6.2.0" + +"@inquirer/input@^1.2.14": + version "1.2.14" + resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-1.2.14.tgz#8951867618bb5cd16dd096e02404eec225a92207" + integrity sha512-tISLGpUKXixIQue7jypNEShrdzJoLvEvZOJ4QRsw5XTfrIYfoWFqAjMQLerGs9CzR86yAI89JR6snHmKwnNddw== + dependencies: + "@inquirer/core" "^5.1.1" + "@inquirer/type" "^1.1.5" + chalk "^4.1.2" + +"@inquirer/password@^1.1.14": + version "1.1.14" + resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-1.1.14.tgz#c1fc139efe84a38986870a1bcf80718050f82bbf" + integrity sha512-vL2BFxfMo8EvuGuZYlryiyAB3XsgtbxOcFs4H9WI9szAS/VZCAwdVqs8rqEeaAf/GV/eZOghIOYxvD91IsRWSg== + dependencies: + "@inquirer/input" "^1.2.14" + "@inquirer/type" "^1.1.5" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + +"@inquirer/type@^1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-1.1.5.tgz#b8c171f755859c8159b10e41e1e3a88f0ca99d7f" + integrity sha512-wmwHvHozpPo4IZkkNtbYenem/0wnfI6hvOcGKmPEa0DwuaH5XUQzFqy6OpEpjEegZMhYIk8HDYITI16BPLtrRA== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -1000,10 +1053,10 @@ wordwrap "^1.0.0" wrap-ansi "^7.0.0" -"@oclif/core@^3.0.4", "@oclif/core@^3.15.0", "@oclif/core@^3.15.1", "@oclif/core@^3.3.1": - version "3.15.1" - resolved "https://registry.yarnpkg.com/@oclif/core/-/core-3.15.1.tgz#e03fa775d658e76056150ac0c7b8097b6f51ab9c" - integrity sha512-d4457zVo2agLoJG97CmdY6M3BeP5sogBP3BtP65hUvJH6wA6Us1hdY3UiPPtD/ZzZImq7cATVMABuCF9tM+rWA== +"@oclif/core@^3.0.4", "@oclif/core@^3.15.0", "@oclif/core@^3.15.1", "@oclif/core@^3.16.0", "@oclif/core@^3.3.1": + version "3.16.0" + resolved "https://registry.yarnpkg.com/@oclif/core/-/core-3.16.0.tgz#682657cb5e4a3262a47e26e0c8a7bf0343acaf76" + integrity sha512-/PIz+udzb59XE8O/bQvqlCtXy6RByEHH0KsrAJNa/ZrqtdsLmeDNJcHdgygFHx+nz+PYMoUzsyzJMau++EDNoQ== dependencies: ansi-escapes "^4.3.2" ansi-styles "^4.3.0" @@ -1382,7 +1435,7 @@ chalk "^4" inquirer "^8.2.5" -"@salesforce/sf-plugins-core@^5.0.12", "@salesforce/sf-plugins-core@^5.0.13": +"@salesforce/sf-plugins-core@^5.0.12": version "5.0.13" resolved "https://registry.yarnpkg.com/@salesforce/sf-plugins-core/-/sf-plugins-core-5.0.13.tgz#f2941527d66ded5750a6646e146af047ab72acc9" integrity sha512-b5R8krKeOIkW0hPxvfpm8T5tCSyWW7MDERnJwm/FXq4ueUJsC1/TCWSscyVKPSZ0VRcEFbzOWKJvpV/omB1D9w== @@ -1395,6 +1448,19 @@ chalk "^4" inquirer "^8.2.5" +"@salesforce/sf-plugins-core@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@salesforce/sf-plugins-core/-/sf-plugins-core-7.0.0.tgz#56cb4eaafcd04a183938d86c5e93323e037b15ab" + integrity sha512-vl53Ee0/eg9wgvtWro6kX82/943s28Hph/o3lTQk6URorfqMC+zH0RGKJj1X0VKeLhDSOCRYXqIu54jE8AZ/3g== + dependencies: + "@inquirer/confirm" "^2.0.15" + "@inquirer/password" "^1.1.14" + "@oclif/core" "^3.16.0" + "@salesforce/core" "^6.4.2" + "@salesforce/kit" "^3.0.15" + "@salesforce/ts-types" "^2.0.9" + chalk "^5.3.0" + "@salesforce/telemetry@^4.1.15": version "4.1.18" resolved "https://registry.yarnpkg.com/@salesforce/telemetry/-/telemetry-4.1.18.tgz#d05ea6827e733fe6a008edad9a3a585bebaaf854" @@ -1709,10 +1775,17 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.6.tgz#818551d39113081048bdddbef96701b4e8bb9d1b" integrity sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg== -"@types/node@*": - version "20.8.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.9.tgz#646390b4fab269abce59c308fc286dcd818a2b08" - integrity sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg== +"@types/mute-stream@^0.0.4": + version "0.0.4" + resolved "https://registry.yarnpkg.com/@types/mute-stream/-/mute-stream-0.0.4.tgz#77208e56a08767af6c5e1237be8888e2f255c478" + integrity sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow== + dependencies: + "@types/node" "*" + +"@types/node@*", "@types/node@^20.9.0": + version "20.10.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.6.tgz#a3ec84c22965802bf763da55b2394424f22bfbb5" + integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw== dependencies: undici-types "~5.26.4" @@ -1808,6 +1881,11 @@ "@types/expect" "^1.20.4" "@types/node" "*" +"@types/wrap-ansi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz#18b97a972f94f60a679fd5c796d96421b9abb9fd" + integrity sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g== + "@typescript-eslint/eslint-plugin@^6.10.0": version "6.11.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.11.0.tgz#52aae65174ff526576351f9ccd41cea01001463f" @@ -2858,10 +2936,10 @@ cli-progress@^3.12.0: dependencies: string-width "^4.2.3" -cli-spinners@^2.5.0: - version "2.9.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.1.tgz#9c0b9dad69a6d47cbb4333c14319b060ed395a35" - integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ== +cli-spinners@^2.5.0, cli-spinners@^2.9.1: + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-table3@^0.6.3: version "0.6.3" @@ -2884,6 +2962,11 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + cliui@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -4020,7 +4103,7 @@ faye@^1.4.0: tough-cookie "*" tunnel-agent "*" -figures@^3.0.0: +figures@^3.0.0, figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== @@ -6389,7 +6472,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -mute-stream@~1.0.0: +mute-stream@^1.0.0, mute-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== @@ -7977,6 +8060,11 @@ run-async@^2.0.0, run-async@^2.4.0: resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== +run-async@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-3.0.0.tgz#42a432f6d76c689522058984384df28be379daad" + integrity sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q== + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -8192,7 +8280,7 @@ signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: +signal-exit@^4.0.1, signal-exit@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==