'use strict'; const assert = require('node:assert/strict'); const crypto = require('crypto'); const fs = require('fs'); const os = require('os'); const path = require('path'); const test = require('node:test'); const { PINNED_ETAHEN, createPs4PkgInstallerAdapter, validateOrder } = require('../../src/services/ps4-pkg-installer-adapter'); const evidence = () => ({ ...PINNED_ETAHEN }); const component = (type = 'base', data = 'pkg') => ({ componentId: type, type, size: Buffer.byteLength(data), sha256: crypto.createHash('sha256').update(data).digest('hex') }); function adapter(overrides = {}) { let postScanVerified = overrides.postScanVerified ?? true; const calls = []; const value = createPs4PkgInstallerAdapter({ mode: overrides.mode || 'dpi', versionEvidenceProvider: overrides.versionEvidenceProvider || evidence, transport: overrides.transport || { probe: async () => ({ reachable: true }), handoff: async input => { calls.push(input); return { res: '0' }; } }, urlPolicy: overrides.urlPolicy || (async input => ({ allowed: true, url: input.url })), artifactServer: overrides.artifactServer, allowedRoots: overrides.allowedRoots || [], postScan: { verify: async () => ({ verified: postScanVerified, scanId: 'scan-1' }) }, timeoutMs: overrides.timeoutMs || 50 }); return { value, calls, setPostScan(value) { postScanVerified = value; } }; } test('version-pinned fake DPI accepts handoff but only post-scan returns installed evidence', async () => { const fixture = adapter(); const probe = await fixture.value.probe(); assert.equal(probe.available, true); assert.equal(probe.version, '2.5B'); assert.equal(probe.capabilities.installedEvidenceFromResponse, false); const item = component(); const output = await fixture.value.execute({ component: item, handoff: { url: 'https://packages.example/base.pkg' } }); assert.deepEqual({ handoffAccepted: output.handoffAccepted, installed: output.installed, requiresPostScan: output.requiresPostScan }, { handoffAccepted: true, installed: false, requiresPostScan: true }); fixture.setPostScan(false); assert.equal((await fixture.value.verify({ component: item, target: {}, outputEvidence: output })).verified, false); fixture.setPostScan(true); const verified = await fixture.value.verify({ component: item, target: {}, outputEvidence: output }); assert.equal(verified.verified, true); assert.equal(verified.source, 'post-install-scan'); }); test('base, update, DLC and unlocker order is deterministic and invalid order fails', () => { assert.deepEqual(validateOrder(['base', 'update', 'dlc', 'unlocker'].map(type => ({ componentId: type, type }))), ['base', 'update', 'dlc', 'unlocker']); assert.throws(() => validateOrder([{ componentId: 'update', type: 'update' }, { componentId: 'base', type: 'base' }]), error => error.code === 'PKG_INSTALL_ORDER'); assert.throws(() => validateOrder([{ componentId: 'base1', type: 'base' }, { componentId: 'base2', type: 'base' }]), error => error.code === 'PKG_INSTALL_ORDER'); }); test('file handoff enforces containment, exact size/hash and hash-bound URL policy', async () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-pkg-adapter-')); const outside = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-pkg-outside-')); try { const filePath = path.join(root, 'base.pkg'); fs.writeFileSync(filePath, 'pkg'); const fixture = adapter({ allowedRoots: [root], artifactServer: { expose: async input => ({ url: `https://packages.example/${input.sha256}.pkg` }) }, urlPolicy: async input => ({ allowed: input.url.includes(input.sha256), url: input.url }) }); const output = await fixture.value.execute({ component: component(), handoff: { filePath } }); assert.equal(output.handoffAccepted, true); const outsidePath = path.join(outside, 'base.pkg'); fs.writeFileSync(outsidePath, 'pkg'); await assert.rejects(() => fixture.value.execute({ component: component(), handoff: { filePath: outsidePath } }), error => error.code === 'PKG_HANDOFF_CONTAINMENT'); await assert.rejects(() => fixture.value.execute({ component: { ...component(), sha256: '0'.repeat(64) }, handoff: { filePath } }), error => error.code === 'PKG_HANDOFF_HASH'); const linkedDirectory = path.join(root, 'linked-outside'); fs.symlinkSync(outside, linkedDirectory, process.platform === 'win32' ? 'junction' : 'dir'); let exposed = 0; const hostile = adapter({ allowedRoots: [root], artifactServer: { expose: async () => { exposed += 1; return { url: 'https://packages.example/unsafe.pkg' }; } } }); await assert.rejects(() => hostile.value.execute({ component: component(), handoff: { filePath: path.join(linkedDirectory, 'base.pkg') } }), error => error.code === 'PKG_HANDOFF_CONTAINMENT'); assert.equal(exposed, 0); } finally { fs.rmSync(root, { recursive: true, force: true }); fs.rmSync(outside, { recursive: true, force: true }); } }); test('unsupported version, DPIv2, malformed service, failure and timeout fail safely', async () => { assert.equal((await adapter({ versionEvidenceProvider: async () => ({ ...PINNED_ETAHEN, version: 'future' }) }).value.probe()).available, false); assert.equal((await adapter({ mode: 'dpi-v2' }).value.probe()).reason, 'protocol-unverified'); await assert.rejects(() => adapter({ transport: { probe: async () => ({ reachable: true }), handoff: async () => ({ ok: true }) } }).value.execute({ component: component(), handoff: { url: 'https://packages.example/base.pkg' } }), error => error.code === 'PKG_INSTALL_RESPONSE'); await assert.rejects(() => adapter({ transport: { probe: async () => ({ reachable: false, error: 'offline' }), handoff: async () => ({ res: 0 }) } }).value.execute({ component: component(), handoff: { url: 'https://packages.example/base.pkg' } }), error => error.code === 'PKG_INSTALL_UNAVAILABLE'); await assert.rejects(() => adapter({ timeoutMs: 5, transport: { probe: async () => ({ reachable: true }), handoff: () => new Promise(() => {}) } }).value.execute({ component: component(), handoff: { url: 'https://packages.example/base.pkg' } }), error => error.code === 'PKG_INSTALL_TIMEOUT'); });