@pnpm/deps.security.signatures 1102.0.0 → 1102.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @pnpm/deps.security.signatures
2
2
 
3
+ ## 1102.0.2
4
+
5
+ ### Patch Changes
6
+
7
+ - `pnpm self-update`, `pnpm with`, and automatic package-manager version switching no longer wait through registry retry delays when a configured registry has no signatures and `registry.npmjs.org` is unavailable [#14483](https://github.com/pnpm/pnpm/issues/14483).
8
+
9
+ - Updated dependencies:
10
+ - @pnpm/error@1100.1.4
11
+ - @pnpm/network.fetch@1100.1.15
12
+
13
+ ## 1102.0.1
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies:
18
+ - @pnpm/network.fetch@1100.1.14
19
+
3
20
  ## 1102.0.0
4
21
 
5
22
  ### Major Changes
@@ -104,7 +104,9 @@ export interface VerifyInstalledSignaturesOptions extends VerifySignaturesOption
104
104
  * Signatures are verified against the caller's trusted keys over the installed
105
105
  * integrity, so where the signature bytes come from does not affect what they
106
106
  * prove — a package passes only when some genuine signature validates over the
107
- * bytes actually installed. See https://github.com/pnpm/pnpm/issues/13147.
107
+ * bytes actually installed. The fallback request is attempted once because it
108
+ * is an optional availability check after the primary registry already failed
109
+ * to provide a verifiable signature. See https://github.com/pnpm/pnpm/issues/13147.
108
110
  */
109
111
  fallbackRegistry?: string;
110
112
  }
@@ -16,7 +16,11 @@ export async function verifySignatures(packages, getAuthHeader, opts) {
16
16
  };
17
17
  // RegistriesByScope without signing keys are not counted as audited: there is no
18
18
  // registry trust root to verify against.
19
- const packumentCache = new Map();
19
+ const packumentContext = {
20
+ getAuthHeader,
21
+ opts,
22
+ packumentCache: new Map(),
23
+ };
20
24
  const limit = pLimit(opts.networkConcurrency ?? 16);
21
25
  await Promise.all(packages.map((pkg) => limit(async () => {
22
26
  const keys = keysByRegistry.get(pkg.registry) ?? [];
@@ -25,7 +29,7 @@ export async function verifySignatures(packages, getAuthHeader, opts) {
25
29
  let version;
26
30
  let publishedAt;
27
31
  try {
28
- const packument = await getPackument(pkg, getAuthHeader, opts, packumentCache);
32
+ const packument = await getPackument(pkg, packumentContext);
29
33
  if (!packument)
30
34
  return;
31
35
  result.audited++;
@@ -107,13 +111,13 @@ async function fetchRegistryKeys(registry, getAuthHeader, opts) {
107
111
  // attestations are intentionally handled separately from this registry check.
108
112
  return body.keys.filter(({ keytype, scheme }) => keytype === 'ecdsa-sha2-nistp256' && scheme === 'ecdsa-sha2-nistp256');
109
113
  }
110
- async function getPackument(pkg, getAuthHeader, opts, packumentCache) {
111
- const cacheKey = `${pkg.registry}:${pkg.name}`;
112
- let packument = packumentCache.get(cacheKey);
114
+ async function getPackument(pkg, ctx) {
115
+ const cacheKey = `${ctx.cacheNamespace ?? ''}:${pkg.registry}:${pkg.name}`;
116
+ let packument = ctx.packumentCache.get(cacheKey);
113
117
  if (!packument) {
114
118
  // Multiple installed versions share one full packument fetch.
115
- packument = fetchPackument(pkg, getAuthHeader, opts);
116
- packumentCache.set(cacheKey, packument);
119
+ packument = fetchPackument(pkg, ctx.getAuthHeader, ctx.opts);
120
+ ctx.packumentCache.set(cacheKey, packument);
117
121
  }
118
122
  return packument;
119
123
  }
@@ -267,6 +271,7 @@ export function getNpmSigningKeys() {
267
271
  }
268
272
  export async function verifyInstalledPackageSignatures(packages, trustedKeys, getAuthHeader, opts) {
269
273
  const ctx = {
274
+ cacheNamespace: 'primary',
270
275
  trustedKeys,
271
276
  getAuthHeader,
272
277
  opts,
@@ -301,7 +306,14 @@ async function findSignatureFailure(pkg, ctx) {
301
306
  const { fallbackRegistry } = ctx.opts;
302
307
  if (fallbackRegistry == null || equalRegistries(pkg.registry, fallbackRegistry))
303
308
  return primary;
304
- const secondary = await attemptSignatureVerification(pkg, fallbackRegistry, ctx);
309
+ const secondary = await attemptSignatureVerification(pkg, fallbackRegistry, {
310
+ ...ctx,
311
+ cacheNamespace: 'fallback',
312
+ opts: {
313
+ ...ctx.opts,
314
+ retry: { ...ctx.opts.retry, retries: 0 },
315
+ },
316
+ });
305
317
  // A genuine signature validating over the installed integrity proves the
306
318
  // installed bytes regardless of which registry the primary attempt hit or
307
319
  // what it answered (e.g. a mirror serving stale signatures from a rotated
@@ -332,7 +344,7 @@ async function attemptSignatureVerification(pkg, registry, ctx) {
332
344
  const displayRegistry = redactAndSanitize(registry);
333
345
  let packument;
334
346
  try {
335
- packument = await getPackument({ ...pkg, registry }, ctx.getAuthHeader, ctx.opts, ctx.packumentCache);
347
+ packument = await getPackument({ ...pkg, registry }, ctx);
336
348
  }
337
349
  catch (err) {
338
350
  // The fetch error may echo the request URL, credentials included.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/deps.security.signatures",
3
- "version": "1102.0.0",
3
+ "version": "1102.0.2",
4
4
  "description": "Verify package signatures from npm registries",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -29,17 +29,17 @@
29
29
  "!*.map"
30
30
  ],
31
31
  "dependencies": {
32
- "@pnpm/error": "1100.1.3",
32
+ "@pnpm/error": "1100.1.4",
33
33
  "@pnpm/fetching.types": "1100.0.3",
34
- "@pnpm/network.fetch": "1100.1.13",
35
- "p-limit": "^7.3.1"
34
+ "@pnpm/network.fetch": "1100.1.15",
35
+ "p-limit": "^7.3.2"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@pnpm/logger": "^1100.0.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@jest/globals": "30.4.1",
42
- "@pnpm/deps.security.signatures": "1102.0.0",
42
+ "@pnpm/deps.security.signatures": "1102.0.2",
43
43
  "@pnpm/logger": "1100.0.0",
44
44
  "@pnpm/testing.mock-agent": "1101.0.7"
45
45
  },