mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
64 lines
1.8 KiB
JavaScript
64 lines
1.8 KiB
JavaScript
import crypto from 'node:crypto';
|
|
import fs from 'node:fs';
|
|
|
|
function sha256File(filePath) {
|
|
const hash = crypto.createHash('sha256');
|
|
hash.update(fs.readFileSync(filePath));
|
|
return hash.digest('hex');
|
|
}
|
|
|
|
function checksumFailure(expectedSha256, actualSha256) {
|
|
return `SHA-256 mismatch: expected ${expectedSha256}, received ${actualSha256}`;
|
|
}
|
|
|
|
export function downloadPinnedSource({
|
|
archivePath,
|
|
download,
|
|
expectedSha256,
|
|
urls,
|
|
}) {
|
|
const partialPath = `${archivePath}.partial`;
|
|
const failures = [];
|
|
const sourceUrls = [...urls];
|
|
|
|
if (fs.existsSync(archivePath)) {
|
|
const actualSha256 = sha256File(archivePath);
|
|
if (actualSha256 === expectedSha256) {
|
|
return {
|
|
sourceSha256: actualSha256,
|
|
sourceUrl: null,
|
|
sourceUrls,
|
|
};
|
|
}
|
|
failures.push(
|
|
`cached archive: ${checksumFailure(
|
|
expectedSha256,
|
|
actualSha256
|
|
)}`
|
|
);
|
|
fs.rmSync(archivePath, { force: true });
|
|
}
|
|
|
|
for (const url of sourceUrls) {
|
|
fs.rmSync(partialPath, { force: true });
|
|
try {
|
|
download({ destinationPath: partialPath, url });
|
|
const actualSha256 = sha256File(partialPath);
|
|
if (actualSha256 !== expectedSha256) {
|
|
throw new Error(
|
|
checksumFailure(expectedSha256, actualSha256)
|
|
);
|
|
}
|
|
fs.renameSync(partialPath, archivePath);
|
|
return { sourceSha256: actualSha256, sourceUrl: url, sourceUrls };
|
|
} catch (error) {
|
|
failures.push(`${url}: ${error.message}`);
|
|
fs.rmSync(partialPath, { force: true });
|
|
}
|
|
}
|
|
|
|
throw new Error(
|
|
`Unable to download a verified source archive:\n${failures.join('\n')}`
|
|
);
|
|
}
|