Files
chimera-Public/test/server/ch-1109-ps5-upstream-control-package.test.js

99 lines
6.1 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 { Readable } = require('node:stream');
const { createPs5UpstreamControlPackageService, CONTROL } = require('../../src/services/ps5-upstream-control-package-service');
function fixture() {
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-ps5-control-'));
const bytes = Buffer.from('pinned-open-source-control');
const registrations = [];
const service = createPs5UpstreamControlPackageService({
outputRoot: root,
stateFile: path.join(root, 'state.json'),
descriptor: { ...CONTROL, size: bytes.length, sha256: crypto.createHash('sha256').update(bytes).digest('hex') },
fetchImpl: async url => ({ ok: url === CONTROL.url, status: 200, body: Readable.toWeb(Readable.from(bytes)) }),
inspectPackage: () => ({ format: 'ps5-fih-debug-package', validation: { structurallyValid: true, validationLevel: 'fih-cnt-structural-v3', contentId: CONTROL.contentId, imageCount: 0, imageKey: { profile: 'opaque-filled-0x800' } } }),
inspectInstallGeometry: async () => ({ packageSize: 17, mountImageSize: 17, installedAppPkgSize: 17, provenance: 'signed-image:pfsimage.xml' }),
registrar: async manifest => { registrations.push(manifest); return { packageSetId: 99, titleId: 42 }; },
});
return { root, bytes, registrations, service };
}
test('imports only the exact hash-pinned upstream control atomically', async t => {
const f = fixture(); t.after(() => fs.rmSync(f.root, { recursive: true, force: true }));
const result = await f.service.importPackage();
assert.equal(result.status, 'ready');
assert.equal(result.installTrust.status, 'unproven');
assert.equal(result.installAuthorized, false);
assert.equal(result.packageSetId, 99);
assert.deepEqual(fs.readFileSync(result.absolutePath), f.bytes);
assert.equal(f.registrations[0].controlProfile, 'upstream-stock-9084c0e');
assert.equal(f.registrations[0].components[0].sha256, crypto.createHash('sha256').update(f.bytes).digest('hex'));
assert.equal(fs.readdirSync(path.dirname(result.absolutePath)).some(name => name.endsWith('.tmp')), false);
const proven = await f.service.recordInstallEvidence({ operationId: 'control-op-1', source: 'post-install-console-scan', observed_at: Date.now() });
assert.equal(proven.installTrust.status, 'post-scan-proven');
assert.equal(proven.installAuthorized, false);
assert.equal((await f.service.status()).installTrust.operationId, 'control-op-1');
assert.equal((await f.service.status()).currentArtifactVerified, true);
});
test('status never reports ready when only the historical state remains', async t => {
const f = fixture(); t.after(() => fs.rmSync(f.root, { recursive: true, force: true }));
await f.service.importPackage();
fs.unlinkSync(f.service.targetPath());
const status = await f.service.status();
assert.equal(status.status, 'missing');
assert.equal(status.currentArtifactVerified, false);
assert.equal(status.historicalRegistration.status, 'ready');
});
test('rejects hash drift and unexpected structural profiles without publishing', async t => {
const f = fixture(); t.after(() => fs.rmSync(f.root, { recursive: true, force: true }));
const badHash = createPs5UpstreamControlPackageService({
outputRoot: f.root, stateFile: path.join(f.root, 'bad-state.json'), descriptor: { ...CONTROL, size: f.bytes.length, sha256: '0'.repeat(64) },
fetchImpl: async () => ({ ok: true, status: 200, body: Readable.toWeb(Readable.from(f.bytes)) }), inspectPackage: () => ({}), registrar: async () => ({}),
});
await assert.rejects(badHash.importPackage(), error => error.code === 'PS5_CONTROL_HASH');
assert.equal(fs.existsSync(badHash.targetPath()), false);
const badProfile = createPs5UpstreamControlPackageService({
outputRoot: f.root, stateFile: path.join(f.root, 'profile-state.json'), descriptor: { ...CONTROL, size: f.bytes.length, sha256: crypto.createHash('sha256').update(f.bytes).digest('hex') },
fetchImpl: async () => ({ ok: true, status: 200, body: Readable.toWeb(Readable.from(f.bytes)) }), inspectPackage: () => ({ format: 'ps5-fih-debug-package', validation: { contentId: CONTROL.contentId, errors: [{ code: 'FIH_MAGIC' }] } }), registrar: async () => ({}),
});
await assert.rejects(badProfile.importPackage(), error => error.code === 'PS5_CONTROL_PROFILE');
assert.equal(fs.existsSync(badProfile.targetPath()), false);
});
test('control routes remain separate and require an exact destructive confirmation', () => {
const registry = fs.readFileSync('src/server/create-registry.js', 'utf8');
assert.match(registry, /ps5-native-packages:control-status[\s\S]*classification: 'read-only'/);
assert.match(registry, /ps5-native-packages:control-import[\s\S]*classification: 'mutating'/);
assert.match(registry, /ps5-native-packages:control-restore[\s\S]*classification: 'destructive'[\s\S]*INSTALL PS5 UPSTREAM CONTROL PACKAGE/);
assert.match(registry, /ps5-native-packages:control-restore-verify[\s\S]*classification: 'mutating'/);
assert.match(registry, /PPSA99099[\s\S]*post-install-console-scan/);
});
test('control UI and both bridges expose import, exact-confirmed restore and post-scan verification', () => {
const preload = fs.readFileSync('preload.js', 'utf8');
const web = fs.readFileSync('renderer/pork-web-shim.js', 'utf8');
const main = fs.readFileSync('main.js', 'utf8');
const modal = fs.readFileSync('renderer/modules/modal.js', 'utf8');
const surface = `${fs.readFileSync('renderer/index.html', 'utf8')}\n${modal}`;
const css = fs.readFileSync('renderer/styles/ps5-native-packages.css', 'utf8');
for (const source of [preload, web]) {
assert.match(source, /ps5UpstreamControl/);
assert.match(source, /ps5-native-packages:control-/);
}
assert.match(main, /PS5_CONTROL_SERVER_REQUIRED/);
assert.match(surface, /ps5-upstream-control-import/);
assert.match(modal, /INSTALL PS5 UPSTREAM CONTROL PACKAGE/);
assert.match(modal, /ps5UpstreamControl\('restore-verify'/);
assert.match(css, /ps5-upstream-control/);
});