{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../../src/asar/integrity.ts"],"names":[],"mappings":"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","sourcesContent":["import { FilterStats, log, statOrNull, walk } from \"builder-util\"\nimport { createHash } from \"crypto\"\nimport { createReadStream } from \"fs\"\nimport { readdir } from \"fs/promises\"\nimport * as path from \"path\"\nimport { FileMatcher } from \"../fileMatcher\"\nimport { NodeIntegrity, readAsarHeader } from \"./asar\"\n\nexport interface AsarIntegrityOptions {\n readonly resourcesPath: string\n readonly resourcesRelativePath: string\n readonly resourcesDestinationPath: string\n readonly extraResourceMatchers: Array | null\n}\n\nexport interface HeaderHash {\n algorithm: \"SHA256\"\n hash: string\n}\n\nexport interface AsarIntegrity {\n [key: string]: HeaderHash\n}\n\nexport async function computeData({ resourcesPath, resourcesRelativePath, resourcesDestinationPath, extraResourceMatchers }: AsarIntegrityOptions): Promise {\n type Match = Pick\n type IntegrityMap = {\n [filepath: string]: string\n }\n const isAsar = (filepath: string) => filepath.endsWith(\".asar\")\n\n const resources = await readdir(resourcesPath)\n const resourceAsars = resources.filter(isAsar).reduce(\n (prev, filename) => ({\n ...prev,\n [path.join(resourcesRelativePath, filename)]: path.join(resourcesPath, filename),\n }),\n {}\n )\n\n const extraResources = await Promise.all(\n (extraResourceMatchers ?? []).map(async (matcher: FileMatcher): Promise => {\n const { from, to } = matcher\n const stat = await statOrNull(from)\n if (stat == null) {\n log.warn({ from }, `file source doesn't exist`)\n return []\n }\n if (stat.isFile()) {\n return [{ from, to }]\n }\n\n if (matcher.isEmpty() || matcher.containsOnlyIgnore()) {\n matcher.prependPattern(\"**/*\")\n }\n const matcherFilter = matcher.createFilter()\n const extraResourceMatches = await walk(matcher.from, (file: string, stats: FilterStats) => matcherFilter(file, stats) || stats.isDirectory())\n return extraResourceMatches.map(from => ({ from, to: matcher.to }))\n })\n )\n const extraResourceAsars = extraResources\n .flat(1)\n .filter(match => isAsar(match.from))\n .reduce((prev, { to, from }) => {\n const prefix = path.relative(resourcesDestinationPath, to)\n return {\n ...prev,\n [path.join(resourcesRelativePath, prefix, path.basename(from))]: from,\n }\n }, {})\n\n // sort to produce constant result\n const allAsars = [...Object.entries(resourceAsars), ...Object.entries(extraResourceAsars)].sort(([name1], [name2]) => name1.localeCompare(name2))\n const hashes = await Promise.all(allAsars.map(async ([, from]) => hashHeader(from)))\n const asarIntegrity: AsarIntegrity = {}\n for (let i = 0; i < allAsars.length; i++) {\n const [asar] = allAsars[i]\n asarIntegrity[asar] = hashes[i]\n }\n return asarIntegrity\n}\n\nasync function hashHeader(file: string): Promise {\n const hash = createHash(\"sha256\")\n const { header } = await readAsarHeader(file)\n hash.update(header)\n return {\n algorithm: \"SHA256\",\n hash: hash.digest(\"hex\"),\n }\n}\n\nexport function hashFile(file: string, blockSize = 4 * 1024 * 1024): Promise {\n return new Promise((resolve, reject) => {\n const hash = createHash(\"sha256\")\n\n const blocks = new Array()\n\n let blockBytes = 0\n let blockHash = createHash(\"sha256\")\n\n function updateBlockHash(chunk: Buffer) {\n let off = 0\n while (off < chunk.length) {\n const toHash = Math.min(blockSize - blockBytes, chunk.length - off)\n blockHash.update(chunk.slice(off, off + toHash))\n off += toHash\n blockBytes += toHash\n\n if (blockBytes === blockSize) {\n blocks.push(blockHash.digest(\"hex\"))\n blockHash = createHash(\"sha256\")\n blockBytes = 0\n }\n }\n }\n\n createReadStream(file)\n .on(\"data\", it => {\n // Note that `it` is a Buffer anyway so this cast is a no-op\n updateBlockHash(Buffer.from(it))\n hash.update(it)\n })\n .on(\"error\", reject)\n .on(\"end\", () => {\n if (blockBytes !== 0) {\n blocks.push(blockHash.digest(\"hex\"))\n }\n resolve({\n algorithm: \"SHA256\",\n hash: hash.digest(\"hex\"),\n blockSize,\n blocks,\n })\n })\n })\n}\n\nexport function hashFileContents(contents: Buffer | string, blockSize = 4 * 1024 * 1024): NodeIntegrity {\n const buffer = Buffer.from(contents)\n const hash = createHash(\"sha256\")\n hash.update(buffer)\n\n const blocks = new Array()\n\n for (let off = 0; off < buffer.length; off += blockSize) {\n const blockHash = createHash(\"sha256\")\n blockHash.update(buffer.slice(off, off + blockSize))\n blocks.push(blockHash.digest(\"hex\"))\n }\n\n return {\n algorithm: \"SHA256\",\n hash: hash.digest(\"hex\"),\n blockSize,\n blocks,\n }\n}\n"]}