@vltpkg/package-info 1.0.0-rc.25 → 1.0.0-rc.26
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/dist/index.js +44 -4
- package/package.json +15 -14
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { asPackument, isIntegrity } from '@vltpkg/types';
|
|
|
9
9
|
import ssri from 'ssri';
|
|
10
10
|
import { Monorepo } from '@vltpkg/workspaces';
|
|
11
11
|
import { XDG } from '@vltpkg/xdg';
|
|
12
|
-
import { randomBytes } from 'node:crypto';
|
|
12
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
13
13
|
import { mkdir, readFile, rm, stat, symlink, unlink, writeFile, } from 'node:fs/promises';
|
|
14
14
|
import { basename, dirname, resolve as pathResolve, relative, } from 'node:path';
|
|
15
15
|
import { create as tarC } from 'tar';
|
|
@@ -67,7 +67,11 @@ export class PackageInfoClient {
|
|
|
67
67
|
spec = Spec.parse(spec, this.options);
|
|
68
68
|
const { from = this.#projectRoot, integrity, resolved } = options;
|
|
69
69
|
const f = spec.final;
|
|
70
|
-
|
|
70
|
+
// Track whether integrity/resolved came from the caller (e.g. lockfile)
|
|
71
|
+
// vs freshly resolved. We only verify tarball integrity on net-new
|
|
72
|
+
// installs (fresh resolution), not when replaying from lockfile.
|
|
73
|
+
const fromLockfile = !!(integrity && resolved);
|
|
74
|
+
const r = fromLockfile ?
|
|
71
75
|
{ resolved, integrity, spec }
|
|
72
76
|
: await this.resolve(spec, options);
|
|
73
77
|
switch (f.type) {
|
|
@@ -114,8 +118,28 @@ export class PackageInfoClient {
|
|
|
114
118
|
response.checkIntegrity({ spec, url: resolved })) {
|
|
115
119
|
this.#trustedIntegrities.set(r.resolved, response.integrity);
|
|
116
120
|
}
|
|
121
|
+
const buf = response.buffer();
|
|
122
|
+
// Verify tarball integrity against the manifest's dist.integrity.
|
|
123
|
+
// This is a supply-chain security measure: the registry may not
|
|
124
|
+
// validate integrity, so we do it client-side on every fresh
|
|
125
|
+
// download. Skip when integrity came from lockfile/cache (it was
|
|
126
|
+
// already verified on first install).
|
|
127
|
+
if (r.integrity && !fromLockfile) {
|
|
128
|
+
const hash = createHash('sha512');
|
|
129
|
+
hash.update(buf);
|
|
130
|
+
const computed = `sha512-${hash.digest('base64')}`;
|
|
131
|
+
if (computed !== r.integrity) {
|
|
132
|
+
throw error('Tarball integrity check failed', {
|
|
133
|
+
code: 'EINTEGRITY',
|
|
134
|
+
spec,
|
|
135
|
+
url: r.resolved,
|
|
136
|
+
wanted: r.integrity,
|
|
137
|
+
found: computed,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
117
141
|
try {
|
|
118
|
-
await this.tarPool.unpack(
|
|
142
|
+
await this.tarPool.unpack(buf, target);
|
|
119
143
|
}
|
|
120
144
|
catch (er) {
|
|
121
145
|
throw this.#resolveError(spec, options, 'tar unpack failed', { cause: er });
|
|
@@ -292,7 +316,23 @@ export class PackageInfoClient {
|
|
|
292
316
|
response.checkIntegrity({ spec, url: tarball })) {
|
|
293
317
|
this.#trustedIntegrities.set(tarball, response.integrity);
|
|
294
318
|
}
|
|
295
|
-
|
|
319
|
+
const buf = response.buffer();
|
|
320
|
+
// Verify tarball integrity against the manifest's dist.integrity.
|
|
321
|
+
if (integrity) {
|
|
322
|
+
const hash = createHash('sha512');
|
|
323
|
+
hash.update(buf);
|
|
324
|
+
const computed = `sha512-${hash.digest('base64')}`;
|
|
325
|
+
if (computed !== integrity) {
|
|
326
|
+
throw error('Tarball integrity check failed', {
|
|
327
|
+
code: 'EINTEGRITY',
|
|
328
|
+
spec,
|
|
329
|
+
url: tarball,
|
|
330
|
+
wanted: integrity,
|
|
331
|
+
found: computed,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return buf;
|
|
296
336
|
}
|
|
297
337
|
case 'git': {
|
|
298
338
|
const { remoteURL, gitRemote, gitCommittish, gitSelectorParsed, } = f;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vltpkg/package-info",
|
|
3
3
|
"description": "Resolve and fetch package metadata and tarballs",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.26",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/vltpkg/vltpkg.git",
|
|
@@ -9,19 +9,20 @@
|
|
|
9
9
|
},
|
|
10
10
|
"author": {
|
|
11
11
|
"name": "vlt technology inc.",
|
|
12
|
-
"email": "support@vlt.sh"
|
|
12
|
+
"email": "support@vlt.sh",
|
|
13
|
+
"url": "http://vlt.sh"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
|
-
"@vltpkg/error-cause": "1.0.0-rc.
|
|
16
|
-
"@vltpkg/git": "1.0.0-rc.
|
|
17
|
-
"@vltpkg/package-json": "1.0.0-rc.
|
|
18
|
-
"@vltpkg/pick-manifest": "1.0.0-rc.
|
|
19
|
-
"@vltpkg/registry-client": "1.0.0-rc.
|
|
20
|
-
"@vltpkg/spec": "1.0.0-rc.
|
|
21
|
-
"@vltpkg/tar": "1.0.0-rc.
|
|
22
|
-
"@vltpkg/types": "1.0.0-rc.
|
|
23
|
-
"@vltpkg/workspaces": "1.0.0-rc.
|
|
24
|
-
"@vltpkg/xdg": "1.0.0-rc.
|
|
16
|
+
"@vltpkg/error-cause": "1.0.0-rc.26",
|
|
17
|
+
"@vltpkg/git": "1.0.0-rc.26",
|
|
18
|
+
"@vltpkg/package-json": "1.0.0-rc.26",
|
|
19
|
+
"@vltpkg/pick-manifest": "1.0.0-rc.26",
|
|
20
|
+
"@vltpkg/registry-client": "1.0.0-rc.26",
|
|
21
|
+
"@vltpkg/spec": "1.0.0-rc.26",
|
|
22
|
+
"@vltpkg/tar": "1.0.0-rc.26",
|
|
23
|
+
"@vltpkg/types": "1.0.0-rc.26",
|
|
24
|
+
"@vltpkg/workspaces": "1.0.0-rc.26",
|
|
25
|
+
"@vltpkg/xdg": "1.0.0-rc.26",
|
|
25
26
|
"ssri": "^13.0.0",
|
|
26
27
|
"tar": "^7.5.2"
|
|
27
28
|
},
|
|
@@ -30,8 +31,8 @@
|
|
|
30
31
|
"@types/node": "^22.19.2",
|
|
31
32
|
"@types/pacote": "^11.1.8",
|
|
32
33
|
"@vltpkg/benchmark": "0.0.0",
|
|
33
|
-
"@vltpkg/cache-unzip": "1.0.0-rc.
|
|
34
|
-
"@vltpkg/vlt-json": "1.0.0-rc.
|
|
34
|
+
"@vltpkg/cache-unzip": "1.0.0-rc.26",
|
|
35
|
+
"@vltpkg/vlt-json": "1.0.0-rc.26",
|
|
35
36
|
"eslint": "^9.39.1",
|
|
36
37
|
"pacote": "^21.0.4",
|
|
37
38
|
"prettier": "^3.7.4",
|