import './setup.mjs'; import test from 'node:test'; import assert from 'node:assert/strict'; import { load } from './setup.mjs'; const { parseIntunewin } = await load('../services/intunewinParser.js'); // --- Minimal stored-method (no compression) ZIP builder for fixtures -------- function crc32(buf) { let crc = 0xffffffff; for (let i = 0; i < buf.length; i++) { crc ^= buf[i]; for (let j = 0; j < 8; j++) crc = (crc >>> 1) ^ (0xedb88320 & -(crc & 1)); } return (crc ^ 0xffffffff) >>> 0; } function makeStoredZip(entries) { const locals = []; const centrals = []; let offset = 0; for (const { name, data } of entries) { const nameBuf = Buffer.from(name, 'utf8'); const crc = crc32(data); const local = Buffer.alloc(30); local.writeUInt32LE(0x04034b50, 0); local.writeUInt16LE(20, 4); local.writeUInt16LE(0, 8); // method = stored local.writeUInt32LE(crc, 14); local.writeUInt32LE(data.length, 18); local.writeUInt32LE(data.length, 22); local.writeUInt16LE(nameBuf.length, 26); const localRecord = Buffer.concat([local, nameBuf, data]); const central = Buffer.alloc(46); central.writeUInt32LE(0x02014b50, 0); central.writeUInt16LE(20, 4); central.writeUInt16LE(20, 6); central.writeUInt16LE(0, 10); // method = stored central.writeUInt32LE(crc, 16); central.writeUInt32LE(data.length, 20); central.writeUInt32LE(data.length, 24); central.writeUInt16LE(nameBuf.length, 28); central.writeUInt32LE(offset, 42); centrals.push(Buffer.concat([central, nameBuf])); locals.push(localRecord); offset += localRecord.length; } const cd = Buffer.concat(centrals); const localsBuf = Buffer.concat(locals); const eocd = Buffer.alloc(22); eocd.writeUInt32LE(0x06054b50, 0); eocd.writeUInt16LE(entries.length, 8); eocd.writeUInt16LE(entries.length, 10); eocd.writeUInt32LE(cd.length, 12); eocd.writeUInt32LE(localsBuf.length, 16); return Buffer.concat([localsBuf, cd, eocd]); } const detectionXml = ` Contoso VPN 2048 IntunePackage.intunewin ContosoVpnSetup.exe QUJDRA== RUZHSA== SUpLTA== TU5PUA== ProfileVersion1 UVJTVA== SHA256 `; const encryptedPayload = Buffer.from('this-stands-in-for-the-encrypted-intunewin-bytes'); const fixture = makeStoredZip([ { name: 'IntuneWinPackage/Metadata/Detection.xml', data: Buffer.from(detectionXml, 'utf8') }, { name: 'IntuneWinPackage/Contents/IntunePackage.intunewin', data: encryptedPayload } ]); test('parses setup file, sizes, and encrypted payload', () => { const parsed = parseIntunewin(fixture); assert.equal(parsed.setupFile, 'ContosoVpnSetup.exe'); assert.equal(parsed.unencryptedContentSize, 2048); assert.equal(parsed.encryptedContentSize, encryptedPayload.length); assert.ok(parsed.encryptedContent.equals(encryptedPayload)); }); test('maps EncryptionInfo to Graph fileEncryptionInfo', () => { const { fileEncryptionInfo } = parseIntunewin(fixture); assert.equal(fileEncryptionInfo.encryptionKey, 'QUJDRA=='); assert.equal(fileEncryptionInfo.macKey, 'RUZHSA=='); assert.equal(fileEncryptionInfo.initializationVector, 'SUpLTA=='); assert.equal(fileEncryptionInfo.mac, 'TU5PUA=='); assert.equal(fileEncryptionInfo.profileIdentifier, 'ProfileVersion1'); assert.equal(fileEncryptionInfo.fileDigest, 'UVJTVA=='); assert.equal(fileEncryptionInfo.fileDigestAlgorithm, 'SHA256'); }); test('rejects a non-.intunewin buffer', () => { assert.throws(() => parseIntunewin(Buffer.from('not a zip at all'))); });