1
mirror of https://github.com/jakejarvis/hugo-extended.git synced 2025-04-26 13:28:28 -04:00

Validate download integrity with checksum (closes #1)

This commit is contained in:
Jake Jarvis 2021-06-01 21:24:31 -04:00
parent bf4f6bb7e3
commit e8f5de5e96
Signed by: jake
GPG Key ID: 2B0C9CF251E69A39
3 changed files with 56 additions and 13 deletions

View File

@ -4,6 +4,7 @@ const fs = require("fs");
const path = require("path");
const { https } = require("follow-redirects");
const decompress = require('decompress');
const sumchecker = require('sumchecker');
(async () => {
install()
@ -22,6 +23,7 @@ async function install() {
// Hugo Extended supports: macOS x64, macOS ARM64, Linux x64, Windows x64.
// all other combos fall back to vanilla Hugo.
const checksumFile = `hugo_${version}_checksums.txt`
const downloadFile =
process.platform === 'darwin' && process.arch === 'x64'
? `hugo_extended_${version}_macOS-64bit.tar.gz` :
@ -61,8 +63,10 @@ async function install() {
if (!downloadFile) throw "Are you sure this platform is supported?";
let downloadUrl = downloadBaseUrl + downloadFile;
let checksumUrl = downloadBaseUrl + checksumFile;
let vendorDir = path.join(__dirname, 'vendor');
let archivePath = path.join(vendorDir, downloadFile);
let checksumPath = path.join(vendorDir, checksumFile);
let binName = process.platform === 'win32' ? 'hugo.exe' : 'hugo';
let binPath = path.join(vendorDir, binName);
@ -87,16 +91,39 @@ async function install() {
);
}).on('error', reject));
// TODO: validate the checksum of the download
// https://github.com/jakejarvis/hugo-extended/issues/1
// fetch the checksum file from GitHub
await new Promise((resolve, reject) => https.get(checksumUrl, response => {
// throw an error immediately if the download failed
if (response.statusCode !== 200) {
response.resume();
reject(new Error(`Download failed: status code ${response.statusCode} from ${checksumUrl}`));
return;
}
// pipe the response directly to a file
response.pipe(
fs.createWriteStream(checksumPath)
.on('finish', resolve)
.on('error', reject)
);
}).on('error', reject));
// validate the checksum of the download
const checker = new sumchecker.ChecksumValidator('sha256', checksumPath, {
defaultTextEncoding: 'binary'
});
await checker.validate(vendorDir, downloadFile);
// extract the downloaded file
await decompress(archivePath, vendorDir);
} finally {
// delete the downloaded archive when finished
if (fs.existsSync(archivePath)) {
if (fs.existsSync(archivePath))
await fs.promises.unlink(archivePath);
}
// ...and the checksum file
if (fs.existsSync(checksumPath))
await fs.promises.unlink(checksumPath);
}
// return the full path to our Hugo binary

31
package-lock.json generated
View File

@ -11,7 +11,8 @@
"dependencies": {
"cross-spawn": "^7.0.3",
"decompress": "^4.2.1",
"follow-redirects": "^1.14.1"
"follow-redirects": "^1.14.1",
"sumchecker": "^3.0.1"
},
"bin": {
"hugo": "cli.js",
@ -501,7 +502,6 @@
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@ -515,7 +515,6 @@
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"dependencies": {
"ms": "2.1.2"
},
@ -1522,8 +1521,7 @@
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/nanoid": {
"version": "3.1.20",
@ -1979,6 +1977,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/sumchecker": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
"integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
"dependencies": {
"debug": "^4.1.0"
},
"engines": {
"node": ">= 8.0"
}
},
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@ -2692,7 +2701,6 @@
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
"dev": true,
"requires": {
"ms": "2.1.2"
}
@ -3441,8 +3449,7 @@
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"nanoid": {
"version": "3.1.20",
@ -3767,6 +3774,14 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"sumchecker": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
"integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
"requires": {
"debug": "^4.1.0"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",

View File

@ -25,7 +25,8 @@
"dependencies": {
"cross-spawn": "^7.0.3",
"decompress": "^4.2.1",
"follow-redirects": "^1.14.1"
"follow-redirects": "^1.14.1",
"sumchecker": "^3.0.1"
},
"devDependencies": {
"eslint": "^7.27.0",