Skip to content

Commit

Permalink
fix(deps): devScripts + manual changes (#843)
Browse files Browse the repository at this point in the history
* chore: updates from devScripts

* chore: ux => Ux

---------

Co-authored-by: mshanemc <[email protected]>
  • Loading branch information
svc-cli-bot and mshanemc authored Jun 6, 2024
1 parent 11a605b commit 559ef17
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 110 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
},
"bugs": "https://github.com/forcedotcom/cli/issues",
"dependencies": {
"@oclif/core": "^3.26.6",
"@oclif/core": "^4",
"@salesforce/core": "^7.3.8",
"@salesforce/kit": "^3.1.2",
"@salesforce/plugin-info": "^3.2.7",
"@salesforce/sf-plugins-core": "^9.0.12",
"@salesforce/sf-plugins-core": "^10.0.0",
"got": "^13.0.0",
"npm": "^10.8.1",
"npm-run-path": "^4.0.1",
Expand All @@ -23,7 +23,7 @@
"devDependencies": {
"@oclif/plugin-command-snapshot": "^5.2.0",
"@salesforce/cli-plugins-testkit": "^5.3.9",
"@salesforce/dev-scripts": "^9.1.3",
"@salesforce/dev-scripts": "^10.1.0",
"@salesforce/plugin-command-reference": "^3.0.82",
"@salesforce/plugin-telemetry": "^3.3.12",
"@salesforce/ts-sinon": "^1.4.18",
Expand Down
9 changes: 5 additions & 4 deletions src/hooks/verifyInstallSignature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { Hook } from '@oclif/core';
import { Logger, Messages } from '@salesforce/core';
import { ux } from '@oclif/core';
import { Ux } from '@salesforce/sf-plugins-core/Ux';
import {
ConfigContext,
doInstallationCodeSigningVerification,
Expand All @@ -20,6 +20,7 @@ import {
import { type NpmName, parseNpmName } from '../shared/npmName.js';

export const hook: Hook.PluginsPreinstall = async function (options) {
const ux = new Ux();
if (options.plugin && options.plugin.type === 'npm') {
const logger = await Logger.child('verifyInstallSignature');
const plugin = options.plugin;
Expand Down Expand Up @@ -56,7 +57,7 @@ export const hook: Hook.PluginsPreinstall = async function (options) {

try {
logger.debug('doing verification');
await doInstallationCodeSigningVerification(configContext, { plugin: plugin.name, tag: plugin.tag }, vConfig);
await doInstallationCodeSigningVerification(ux)(configContext, { plugin: plugin.name, tag: plugin.tag }, vConfig);
ux.log('Finished digital signature check.');
} catch (error) {
if (!(error instanceof Error)) {
Expand All @@ -75,10 +76,10 @@ export const hook: Hook.PluginsPreinstall = async function (options) {
const messages = Messages.loadMessages('@salesforce/plugin-trust', 'verify');
ux.log(messages.getMessage('SkipSignatureCheck', [options.plugin.url]));
} else {
await doPrompt(options.plugin.url);
await doPrompt(ux)(options.plugin.url);
}
} else {
await doPrompt();
await doPrompt(ux)();
}
};

Expand Down
103 changes: 53 additions & 50 deletions src/shared/installationVerification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ import { URL } from 'node:url';
import crypto from 'node:crypto';
import fs from 'node:fs';
import { mkdir } from 'node:fs/promises';

import { Ux } from '@salesforce/sf-plugins-core/Ux';
import { Logger, SfError, Messages } from '@salesforce/core';
import got from 'got';
import { ProxyAgent } from 'proxy-agent';
import { ux } from '@oclif/core';
import { prompts } from '@salesforce/sf-plugins-core';
import { maxSatisfying } from 'semver';
import { NpmModule, NpmMeta } from './npmCommand.js';
Expand All @@ -32,11 +31,11 @@ export type ConfigContext = {
cacheDir?: string;
dataDir?: string;
cliRoot?: string;
}
};
export type Verifier = {
verify(): Promise<NpmMeta>;
isAllowListed(): Promise<boolean>;
}
};

class CodeVerifierInfo {
private signature?: Readable;
Expand Down Expand Up @@ -444,62 +443,66 @@ export class InstallationVerification implements Verifier {

export class VerificationConfig {
public verifier?: Verifier;

private ux = new Ux();
// eslint-disable-next-line class-methods-use-this
public log(message: string): void {
ux.log(message);
this.ux.log(message);
}
}

export async function doPrompt(plugin?: string): Promise<void> {
const messages = Messages.loadMessages('@salesforce/plugin-trust', 'verify');
if (
!(await prompts.confirm({
message: messages.getMessage('InstallConfirmation', [plugin ?? 'This plugin']),
ms: 30_000,
}))
) {
throw new SfError('The user canceled the plugin installation.', 'InstallationCanceledError');
}
// they approved the plugin. Let them know how to automate this.
ux.log(messages.getMessage('SuggestAllowList'));
}

export async function doInstallationCodeSigningVerification(
config: ConfigContext,
plugin: { plugin: string; tag: string },
verificationConfig: VerificationConfig
): Promise<void> {
const messages = Messages.loadMessages('@salesforce/plugin-trust', 'verify');

if (await verificationConfig.verifier?.isAllowListed()) {
verificationConfig.log(messages.getMessage('SkipSignatureCheck', [plugin.plugin]));
return;
}
try {
if (!verificationConfig.verifier) {
throw new Error('VerificationConfig.verifier is not set.');
export const doPrompt =
(ux: Ux) =>
async (plugin?: string): Promise<void> => {
const messages = Messages.loadMessages('@salesforce/plugin-trust', 'verify');
if (
!(await prompts.confirm({
message: messages.getMessage('InstallConfirmation', [plugin ?? 'This plugin']),
ms: 30_000,
}))
) {
throw new SfError('The user canceled the plugin installation.', 'InstallationCanceledError');
}
const meta = await verificationConfig.verifier.verify();
if (!meta.verified) {
const err = messages.createError('FailedDigitalSignatureVerification');
throw setErrorName(err, 'FailedDigitalSignatureVerification');
// they approved the plugin. Let them know how to automate this.
ux.log(messages.getMessage('SuggestAllowList'));
};

export const doInstallationCodeSigningVerification =
(ux: Ux) =>
async (
config: ConfigContext,
plugin: { plugin: string; tag: string },
verificationConfig: VerificationConfig
): Promise<void> => {
const messages = Messages.loadMessages('@salesforce/plugin-trust', 'verify');

if (await verificationConfig.verifier?.isAllowListed()) {
verificationConfig.log(messages.getMessage('SkipSignatureCheck', [plugin.plugin]));
return;
}
verificationConfig.log(messages.getMessage('SignatureCheckSuccess', [plugin.plugin]));
} catch (err) {
if (err instanceof Error) {
if (err.name === 'NotSigned' || err.message?.includes('Response code 403')) {
if (!verificationConfig.verifier) {
throw new Error('VerificationConfig.verifier is not set.');
try {
if (!verificationConfig.verifier) {
throw new Error('VerificationConfig.verifier is not set.');
}
const meta = await verificationConfig.verifier.verify();
if (!meta.verified) {
const err = messages.createError('FailedDigitalSignatureVerification');
throw setErrorName(err, 'FailedDigitalSignatureVerification');
}
verificationConfig.log(messages.getMessage('SignatureCheckSuccess', [plugin.plugin]));
} catch (err) {
if (err instanceof Error) {
if (err.name === 'NotSigned' || err.message?.includes('Response code 403')) {
if (!verificationConfig.verifier) {
throw new Error('VerificationConfig.verifier is not set.');
}
return doPrompt(ux)(plugin.plugin);
} else if (err.name === 'PluginNotFound' || err.name === 'PluginAccessDenied') {
throw setErrorName(new SfError(err.message ?? 'The user canceled the plugin installation.'), '');
}
return await doPrompt(plugin.plugin);
} else if (err.name === 'PluginNotFound' || err.name === 'PluginAccessDenied') {
throw setErrorName(new SfError(err.message ?? 'The user canceled the plugin installation.'), '');
throw setErrorName(SfError.wrap(err), err.name);
}
throw setErrorName(SfError.wrap(err), err.name);
}
}
}
};

/**
* Retrieve url content for a host
Expand Down
6 changes: 3 additions & 3 deletions test/hooks/verifyInstallSignatureHook.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { assert, expect, config as chaiConfig } from 'chai';
import sinon from 'sinon';
import { stubMethod } from '@salesforce/ts-sinon';

import { prompts } from '@salesforce/sf-plugins-core';
import { Config, ux } from '@oclif/core';
import { Ux, prompts } from '@salesforce/sf-plugins-core';
import { Config } from '@oclif/core';
import { InstallationVerification, VerificationConfig } from '../../src/shared/installationVerification.js';

chaiConfig.truncateThreshold = 0;
Expand Down Expand Up @@ -39,7 +39,7 @@ describe('plugin install hook', () => {
stubMethod(sandbox, vConfig.verifier, 'isAllowListed').callsFake(async () => false);

promptSpy = stubMethod(sandbox, prompts, 'confirm').resolves(false);
stubMethod(sandbox, ux, 'log').callsFake(() => {});
stubMethod(sandbox, Ux.prototype, 'log').callsFake(() => {});
});

afterEach(() => {
Expand Down
16 changes: 8 additions & 8 deletions test/shared/installationVerification.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { OptionsOfTextResponseBody } from 'got';
import shelljs from 'shelljs';
import { stubMethod } from '@salesforce/ts-sinon';
import { SfError } from '@salesforce/core';
import { prompts } from '@salesforce/sf-plugins-core';
import { Ux, prompts } from '@salesforce/sf-plugins-core';
import Sinon from 'sinon';
import {
ConfigContext,
Expand Down Expand Up @@ -596,7 +596,7 @@ describe('InstallationVerification Tests', () => {
message = _message;
};

await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig);
await doInstallationCodeSigningVerification(new Ux())({}, BLANK_PLUGIN, vConfig);
expect(message).to.include('Successfully');
expect(message).to.include('digital signature');
});
Expand All @@ -615,7 +615,7 @@ describe('InstallationVerification Tests', () => {
} as Verifier;

try {
return await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig);
return await doInstallationCodeSigningVerification(new Ux())({}, BLANK_PLUGIN, vConfig);
} catch (err) {
expect(err).to.have.property('name', 'FailedDigitalSignatureVerification');
}
Expand All @@ -637,7 +637,7 @@ describe('InstallationVerification Tests', () => {
stubMethod(sandbox, prompts, 'confirm').resolves(false);

try {
await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig);
await doInstallationCodeSigningVerification(new Ux())({}, BLANK_PLUGIN, vConfig);
throw new Error('Failure: This should never happen');
} catch (err) {
expect(err).to.have.property('name', 'InstallationCanceledError');
Expand All @@ -660,7 +660,7 @@ describe('InstallationVerification Tests', () => {
stubMethod(sandbox, prompts, 'confirm').resolves(true);

try {
await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig);
await doInstallationCodeSigningVerification(new Ux())({}, BLANK_PLUGIN, vConfig);
throw new Error('Failure: This should never happen');
} catch (err) {
expect(err).to.have.property('name', 'UnexpectedHost');
Expand All @@ -683,7 +683,7 @@ describe('InstallationVerification Tests', () => {
stubMethod(sandbox, prompts, 'confirm').resolves(true);

try {
await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig);
await doInstallationCodeSigningVerification(new Ux())({}, BLANK_PLUGIN, vConfig);
} catch (e) {
assert(e instanceof Error);
const err = new Error("this test shouldn't fail.");
Expand All @@ -708,7 +708,7 @@ describe('InstallationVerification Tests', () => {
stubMethod(sandbox, prompts, 'confirm').resolves(true);

try {
await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig);
await doInstallationCodeSigningVerification(new Ux())({}, BLANK_PLUGIN, vConfig);
} catch (e) {
assert(e instanceof Error);
const err = new Error("this test shouldn't fail.");
Expand All @@ -733,7 +733,7 @@ describe('InstallationVerification Tests', () => {
stubMethod(sandbox, prompts, 'confirm').resolves(true);

try {
await doInstallationCodeSigningVerification({}, BLANK_PLUGIN, vConfig);
await doInstallationCodeSigningVerification(new Ux())({}, BLANK_PLUGIN, vConfig);
} catch (e) {
assert(e instanceof Error);
const err = new Error("this test shouldn't fail.");
Expand Down
Loading

0 comments on commit 559ef17

Please sign in to comment.