84 lines
5.6 KiB
JavaScript
84 lines
5.6 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('node:assert/strict');
|
|
const crypto = require('node:crypto');
|
|
const fs = require('node:fs');
|
|
const os = require('node:os');
|
|
const path = require('node:path');
|
|
const test = require('node:test');
|
|
const { createEtaHenDpiV2PackageInstaller } = require('../../src/services/etahen-dpi-v2-package-installer');
|
|
|
|
function response(body, status = 200, headers = {}) {
|
|
return {
|
|
ok: status >= 200 && status < 300,
|
|
status,
|
|
headers: { get: name => headers[String(name).toLowerCase()] || null },
|
|
text: async () => String(body),
|
|
};
|
|
}
|
|
|
|
test('etaHEN DPI v2 adapter proves the WebUI identity and submits a tokenized package URL', async t => {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-dpi-v2-'));
|
|
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
const filePath = path.join(root, 'IV9999-FAKE00000_00-HOMEBREWLOADER01.pkg');
|
|
const bytes = Buffer.concat([Buffer.from([0x7f, 0x46, 0x49, 0x48]), Buffer.alloc(128, 0x4a)]);
|
|
fs.writeFileSync(filePath, bytes);
|
|
const calls = []; const packageUrl = 'https://chimera.example.test/ps5-native-package/token/sample.pkg';
|
|
const fetch = async (url, options = {}) => {
|
|
calls.push({ url: String(url), options, body: options.body?.getBuffer?.().toString('utf8') || '' });
|
|
if (!options.method) return response('<title>etaHEN DPIv2</title><form action="/upload" method="post" enctype="multipart/form-data">');
|
|
return response('SUCCESS: Installation started');
|
|
};
|
|
const adapter = createEtaHenDpiV2PackageInstaller({
|
|
consoleHost: 'ps5.local', packageRoot: root, fetch,
|
|
createPackageHandoff: async artifact => ({ url: packageUrl, sha256: artifact.sha256, size: artifact.size, expiresAt: Date.now() + 60_000 }),
|
|
});
|
|
const probe = await adapter.probe();
|
|
assert.equal(probe.available, true);
|
|
assert.equal(probe.protocol, 'etahen-dpi-v2-url-v1');
|
|
const result = await adapter.install({ filePath, size: bytes.length, sha256: crypto.createHash('sha256').update(bytes).digest('hex') });
|
|
assert.equal(result.accepted, true);
|
|
assert.equal(result.installed, false);
|
|
assert.equal(result.postScanRequired, true);
|
|
assert.equal(result.response, 'SUCCESS: Installation started');
|
|
const upload = calls.find(call => call.options.method === 'POST');
|
|
assert.equal(upload.url, 'http://ps5.local:12800/upload');
|
|
assert.match(upload.options.headers['content-type'], /^multipart\/form-data; boundary=/);
|
|
assert.match(upload.body, /name="file"/);
|
|
assert.match(upload.body, /name="url"/);
|
|
assert.match(upload.body, new RegExp(packageUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
|
|
assert.equal(upload.body.includes(bytes.toString('hex')), false);
|
|
});
|
|
|
|
test('etaHEN DPI v2 adapter fails closed on identity drift, path escape, hash drift and ambiguous response', async t => {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-dpi-v2-negative-'));
|
|
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
const filePath = path.join(root, 'sample.pkg');
|
|
const bytes = Buffer.concat([Buffer.from([0x7f, 0x46, 0x49, 0x48]), Buffer.alloc(32)]);
|
|
fs.writeFileSync(filePath, bytes);
|
|
const hash = crypto.createHash('sha256').update(bytes).digest('hex');
|
|
const drift = createEtaHenDpiV2PackageInstaller({ consoleHost: 'ps5.local', packageRoot: root, fetch: async () => response('<html>other service</html>') });
|
|
assert.equal((await drift.probe()).available, false);
|
|
await assert.rejects(() => drift.install({ filePath, size: bytes.length, sha256: hash }), error => error.code === 'ETAHEN_DPI_V2_IDENTITY');
|
|
|
|
const outside = path.join(os.tmpdir(), `outside-${crypto.randomUUID()}.pkg`);
|
|
fs.writeFileSync(outside, bytes); t.after(() => fs.rmSync(outside, { force: true }));
|
|
const ambiguous = createEtaHenDpiV2PackageInstaller({ consoleHost: 'ps5.local', packageRoot: root, createPackageHandoff: async () => ({ url: 'https://chimera.example.test/pkg' }), fetch: async (_url, options = {}) => response(options.method ? 'processing' : '<title>etaHEN DPIv2</title><form action="/upload" enctype="multipart/form-data">') });
|
|
await assert.rejects(() => ambiguous.install({ filePath: outside, size: bytes.length, sha256: hash }), error => error.code === 'ETAHEN_DPI_V2_PATH');
|
|
await assert.rejects(() => ambiguous.install({ filePath, size: bytes.length, sha256: '0'.repeat(64) }), error => error.code === 'ETAHEN_DPI_V2_HASH');
|
|
await assert.rejects(() => ambiguous.install({ filePath, size: bytes.length, sha256: hash }), error => error.code === 'ETAHEN_DPI_V2_RESPONSE');
|
|
});
|
|
|
|
test('etaHEN DPI v2 adapter fails closed without a valid tokenized handoff URL', async t => {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-dpi-v2-handoff-'));
|
|
t.after(() => fs.rmSync(root, { recursive: true, force: true }));
|
|
const filePath = path.join(root, 'sample.pkg');
|
|
const bytes = Buffer.concat([Buffer.from([0x7f, 0x46, 0x49, 0x48]), Buffer.alloc(32)]);
|
|
fs.writeFileSync(filePath, bytes); const sha256 = crypto.createHash('sha256').update(bytes).digest('hex');
|
|
const fetch = async () => response('<title>etaHEN DPIv2</title><form action="/upload" enctype="multipart/form-data">');
|
|
const missing = createEtaHenDpiV2PackageInstaller({ consoleHost: 'ps5.local', packageRoot: root, fetch });
|
|
await assert.rejects(() => missing.install({ filePath, size: bytes.length, sha256 }), error => error.code === 'ETAHEN_DPI_V2_HANDOFF');
|
|
const unsafe = createEtaHenDpiV2PackageInstaller({ consoleHost: 'ps5.local', packageRoot: root, fetch, createPackageHandoff: async () => ({ url: 'file:///tmp/sample.pkg' }) });
|
|
await assert.rejects(() => unsafe.install({ filePath, size: bytes.length, sha256 }), error => error.code === 'ETAHEN_DPI_V2_HANDOFF');
|
|
});
|