Skip to content

Commit 53b1fe7

Browse files
authored
feat: add more informative error when fetching latest stable fails (#644)
1 parent 4be72f6 commit 53b1fe7

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

sources/npmRegistryUtils.ts

+23-10
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,27 @@ export function verifySignature({signatures, integrity, packageName, version}: {
3838
packageName: string;
3939
version: string;
4040
}) {
41-
const {npm: keys} = process.env.COREPACK_INTEGRITY_KEYS ?
41+
if (!Array.isArray(signatures) || !signatures.length) throw new Error(`No compatible signature found in package metadata`);
42+
43+
const {npm: trustedKeys} = process.env.COREPACK_INTEGRITY_KEYS ?
4244
JSON.parse(process.env.COREPACK_INTEGRITY_KEYS) as typeof defaultConfig.keys :
4345
defaultConfig.keys;
4446

45-
const key = keys.find(({keyid}) => signatures.some(s => s.keyid === keyid));
46-
const signature = signatures.find(({keyid}) => keyid === key?.keyid);
47-
48-
if (key == null || signature == null) throw new Error(`Cannot find matching keyid: ${JSON.stringify({signatures, keys})}`);
47+
let signature: typeof signatures[0] | undefined;
48+
let key!: string;
49+
for (const k of trustedKeys) {
50+
signature = signatures.find(({keyid}) => keyid === k.keyid);
51+
if (signature != null) {
52+
key = k.key;
53+
break;
54+
}
55+
}
56+
if (signature?.sig == null) throw new UsageError(`The package was not signed by any trusted keys: ${JSON.stringify({signatures, trustedKeys}, undefined, 2)}`);
4957

5058
const verifier = createVerify(`SHA256`);
5159
verifier.end(`${packageName}@${version}:${integrity}`);
5260
const valid = verifier.verify(
53-
`-----BEGIN PUBLIC KEY-----\n${key.key}\n-----END PUBLIC KEY-----`,
61+
`-----BEGIN PUBLIC KEY-----\n${key}\n-----END PUBLIC KEY-----`,
5462
signature.sig,
5563
`base64`,
5664
);
@@ -65,10 +73,15 @@ export async function fetchLatestStableVersion(packageName: string) {
6573
const {version, dist: {integrity, signatures, shasum}} = metadata;
6674

6775
if (!shouldSkipIntegrityCheck()) {
68-
verifySignature({
69-
packageName, version,
70-
integrity, signatures,
71-
});
76+
try {
77+
verifySignature({
78+
packageName, version,
79+
integrity, signatures,
80+
});
81+
} catch (cause) {
82+
// TODO: consider switching to `UsageError` when https://github.com/arcanis/clipanion/issues/157 is fixed
83+
throw new Error(`Corepack cannot download the latest stable version of ${packageName}; you can disable signature verification by setting COREPACK_INTEGRITY_CHECK to 0 in your env, or instruct Corepack to use the latest stable release known by this version of Corepack by setting COREPACK_USE_LATEST to 0`, {cause});
84+
}
7285
}
7386

7487
return `${version}+${

0 commit comments

Comments
 (0)