mirror of
https://github.com/jakejarvis/careful-downloader.git
synced 2025-04-26 06:35:22 -04:00
98 lines
3.7 KiB
JavaScript
98 lines
3.7 KiB
JavaScript
import path from "path";
|
|
import crypto from "crypto";
|
|
import fs from "fs-extra";
|
|
|
|
import debug from "./debug.js";
|
|
|
|
// Check the checksum via a parsed text file containing one or more hashes.
|
|
export const checksumViaFile = async (desiredFile, checksumFile, algorithm, encoding) => {
|
|
debug(`Validating checksum of '${desiredFile}' against hashes listed in '${checksumFile}' (algo: '${algorithm}', encoding: '${encoding}')`);
|
|
|
|
const parsedHashes = await parseChecksumFile(checksumFile);
|
|
debug(`All hashes pulled from the checksums file '${path.basename(checksumFile)}' : ${JSON.stringify(parsedHashes)}`);
|
|
|
|
const generatedHash = await generateHashFromFile(desiredFile, algorithm, encoding);
|
|
debug(`Generated a ${algorithm} hash of '${path.basename(desiredFile)}' => ${generatedHash}`);
|
|
|
|
const correctHash = parsedHashes[path.basename(desiredFile)];
|
|
debug(`Found '${path.basename(desiredFile)}' in '${path.basename(checksumFile)}', provided hash is: ${correctHash}`);
|
|
|
|
if (!correctHash) {
|
|
throw new Error(`'${path.basename(desiredFile)}' isn't listed in checksums file.`);
|
|
}
|
|
|
|
debug(`Checking if generated === provided... ${generatedHash} : ${correctHash}`);
|
|
if (generatedHash !== correctHash) {
|
|
debug(`Nope... ${generatedHash} !== ${correctHash}`);
|
|
throw new Error(`Hash of '${path.basename(desiredFile)}' doesn't match the given checksum.`);
|
|
}
|
|
|
|
debug("Checksum validated via file, it's a match!");
|
|
return true;
|
|
};
|
|
|
|
// Check the checksum via a provided hash.
|
|
export const checksumViaString = async (desiredFile, correctHash, algorithm, encoding) => {
|
|
debug(`Validating checksum of '${desiredFile}' against provided hash '${correctHash}' (algo: '${algorithm}', encoding: '${encoding}')`);
|
|
|
|
const generatedHash = await generateHashFromFile(desiredFile, algorithm, encoding);
|
|
debug(`Generated a ${algorithm} hash of '${path.basename(desiredFile)}' => ${generatedHash}`);
|
|
|
|
debug(`Checking if generated === provided... ${generatedHash} : ${correctHash}`);
|
|
if (generatedHash !== correctHash) {
|
|
debug(`Nope... ${generatedHash} !== ${correctHash}`);
|
|
throw new Error(`Hash of '${path.basename(desiredFile)}' doesn't match the given checksum.`);
|
|
}
|
|
|
|
debug("Checksum validated via string, it's a match!");
|
|
return true;
|
|
};
|
|
|
|
// Takes a path to a file and returns its hash.
|
|
const generateHashFromFile = async (file, algorithm, encoding) => {
|
|
const fileBuffer = fs.readFileSync(file);
|
|
const hashSum = crypto.createHash(algorithm);
|
|
hashSum.update(fileBuffer);
|
|
|
|
return hashSum.digest(encoding);
|
|
};
|
|
|
|
// Largely adapted from sumchecker:
|
|
// https://github.com/malept/sumchecker/blob/28aed640a02787490d033fda56eaee30e24e5a71/src/index.ts#L97
|
|
const parseChecksumFile = async (checksumFile) => {
|
|
// read the text file holding one or more checksums
|
|
const data = fs.readFileSync(checksumFile, { encoding: "utf8" });
|
|
|
|
// https://regexr.com/67k7i
|
|
const lineRegex = /^([\da-fA-F]+) ([ *])(.+)$/;
|
|
|
|
// extract each file and its hash into this object
|
|
const checksums = {};
|
|
|
|
// loop through each line (should be one file & hash each)
|
|
let lineNumber = 0;
|
|
for (const line of data.trim().split(/[\r\n]+/)) {
|
|
lineNumber += 1;
|
|
|
|
// parse the current line using the regex pattern above
|
|
const parsedLine = lineRegex.exec(line);
|
|
|
|
if (parsedLine === null) {
|
|
// didn't match regex
|
|
debug(`Could not parse line number ${lineNumber}`);
|
|
throw new Error(lineNumber, line);
|
|
} else {
|
|
parsedLine.shift();
|
|
|
|
// eslint-disable-next-line no-unused-vars
|
|
const [hash, binary, file] = parsedLine;
|
|
|
|
// save the current file & hash in the checksums object
|
|
checksums[file] = hash;
|
|
}
|
|
}
|
|
|
|
// send back the cleaned up object of filenames & hashes
|
|
return checksums;
|
|
};
|