tachograph 0.1.1 → 0.2.0
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/asset.js +22 -3
- package/install.js +18 -1
- package/package.json +1 -1
package/asset.js
CHANGED
|
@@ -23,10 +23,29 @@ function assetFor(platform, arch) {
|
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
// tagFor normalizes a package version to its release tag (v-prefixed).
|
|
27
|
+
function tagFor(version) {
|
|
28
|
+
return version.startsWith("v") ? version : `v${version}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
26
31
|
// downloadURL builds the GitHub release download URL for a version + asset.
|
|
27
32
|
function downloadURL(version, asset) {
|
|
28
|
-
|
|
29
|
-
|
|
33
|
+
return `https://github.com/kosako/tachograph/releases/download/${tagFor(version)}/${asset}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// checksumsURL is the GoReleaser checksums.txt for the matching release.
|
|
37
|
+
function checksumsURL(version) {
|
|
38
|
+
return `https://github.com/kosako/tachograph/releases/download/${tagFor(version)}/checksums.txt`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// checksumFor parses GoReleaser's "<sha256> <filename>" lines and returns the
|
|
42
|
+
// hex digest for asset, or null when it isn't listed.
|
|
43
|
+
function checksumFor(text, asset) {
|
|
44
|
+
for (const line of text.split("\n")) {
|
|
45
|
+
const [hash, name] = line.trim().split(/\s+/);
|
|
46
|
+
if (name === asset && hash) return hash;
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
30
49
|
}
|
|
31
50
|
|
|
32
|
-
module.exports = { assetFor, downloadURL, PLATFORMS, ARCHES };
|
|
51
|
+
module.exports = { assetFor, downloadURL, checksumsURL, checksumFor, PLATFORMS, ARCHES };
|
package/install.js
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
const fs = require("fs");
|
|
10
10
|
const os = require("os");
|
|
11
11
|
const path = require("path");
|
|
12
|
+
const crypto = require("crypto");
|
|
12
13
|
const { execFileSync } = require("child_process");
|
|
13
|
-
const { assetFor, downloadURL } = require("./asset");
|
|
14
|
+
const { assetFor, downloadURL, checksumsURL, checksumFor } = require("./asset");
|
|
14
15
|
|
|
15
16
|
const { version } = require("./package.json");
|
|
16
17
|
const binDir = path.join(__dirname, "bin");
|
|
@@ -25,6 +26,22 @@ async function main() {
|
|
|
25
26
|
}
|
|
26
27
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
27
28
|
|
|
29
|
+
// Verify the archive against GoReleaser's published checksums.txt before
|
|
30
|
+
// extracting and running it, so a corrupted/tampered/partial download is
|
|
31
|
+
// caught rather than executed.
|
|
32
|
+
const sums = await fetch(checksumsURL(version), { redirect: "follow" });
|
|
33
|
+
if (!sums.ok) {
|
|
34
|
+
throw new Error(`checksums download failed: ${sums.status} ${sums.statusText}`);
|
|
35
|
+
}
|
|
36
|
+
const want = checksumFor(await sums.text(), asset);
|
|
37
|
+
if (!want) {
|
|
38
|
+
throw new Error(`no checksum listed for ${asset}`);
|
|
39
|
+
}
|
|
40
|
+
const got = crypto.createHash("sha256").update(buf).digest("hex");
|
|
41
|
+
if (got !== want) {
|
|
42
|
+
throw new Error(`checksum mismatch for ${asset}: expected ${want}, got ${got}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
28
45
|
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "tacho-"));
|
|
29
46
|
const archive = path.join(tmp, asset);
|
|
30
47
|
fs.writeFileSync(archive, buf);
|
package/package.json
CHANGED