generated from salesforcecli/plugin-template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
verify.ts
114 lines (97 loc) · 3.62 KB
/
verify.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* Copyright (c) 2018, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
import { SfCommand, Flags, loglevel } from '@salesforce/sf-plugins-core';
import { Messages, SfError, Logger } from '@salesforce/core';
import {
ConfigContext,
InstallationVerification,
VerificationConfig,
} from '../../../shared/installationVerification.js';
import { type NpmName, parseNpmName } from '../../../shared/npmName.js';
import { setErrorName } from '../../../shared/errors.js';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-trust', 'verify');
export type VerifyResponse = {
message: string;
verified: boolean;
};
export class Verify extends SfCommand<VerifyResponse> {
public static readonly summary = messages.getMessage('summary');
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessages('examples');
public static readonly hidden: true;
public static readonly flags = {
npm: Flags.string({
char: 'n',
required: true,
summary: messages.getMessage('flags.npm.summary'),
}),
registry: Flags.string({
char: 'r',
summary: messages.getMessage('flags.registry.summary'),
}),
loglevel,
};
private static getVerifier(npmName: NpmName, config: ConfigContext): InstallationVerification {
return new InstallationVerification().setPluginNpmName(npmName).setConfig(config);
}
public async run(): Promise<VerifyResponse> {
const { flags } = await this.parse(Verify);
const logger = await Logger.child('verify');
this.log('Checking for digital signature.');
const npmName = parseNpmName(flags.npm);
logger.debug(`running verify command for npm: ${npmName.name}`);
const vConfig = new VerificationConfig();
const configContext: ConfigContext = {
cacheDir: this.config.cacheDir,
configDir: this.config.configDir,
dataDir: this.config.dataDir,
cliRoot: this.config.root,
};
(['cacheDir', 'configDir', 'dataDir'] as const)
.map((dir) => `${dir}: ${configContext[dir] ?? '<not present on configContext>'}`)
.map((s) => logger.debug(s));
vConfig.verifier = Verify.getVerifier(npmName, configContext);
if (await vConfig.verifier.isAllowListed()) {
const message = messages.getMessage('SkipSignatureCheck', [npmName.name]);
this.log(message);
return {
message,
verified: false,
};
}
if (flags.registry) {
process.env.SF_NPM_REGISTRY = flags.registry;
process.env.SFDX_NPM_REGISTRY = flags.registry;
}
try {
const meta = await vConfig.verifier.verify();
logger.debug(`meta.verified: ${meta.verified ?? '<not present>'}`);
if (!meta.verified) {
const e = messages.createError('FailedDigitalSignatureVerification');
throw setErrorName(e, 'FailedDigitalSignatureVerification');
}
const message = messages.getMessage('SignatureCheckSuccess', [npmName.name]);
this.logSuccess(message);
return { message, verified: true };
} catch (error) {
if (!(error instanceof Error)) {
throw error;
}
logger.debug(`err reported: ${JSON.stringify(error, null, 4)}`);
if (error.name === 'NotSigned') {
const message = messages.getMessage('NotSigned');
this.log(message);
return {
verified: false,
message,
};
}
throw SfError.wrap(error);
}
}
}