'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 database = require('../../src/database'); const { registerPs5NativePackageManifest } = require('../../src/services/ps5-native-package-registration-service'); const { createPs5LaunchReferencePackageService, LAUNCH_REFERENCE } = require('../../src/services/ps5-launch-reference-package-service'); function fixture() { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-ps5-launch-reference-')); const bytes = Buffer.from('pinned-websrv-launch-reference'); const registrations = []; const service = createPs5LaunchReferencePackageService({ outputRoot: root, stateFile: path.join(root, 'state.json'), descriptor: { ...LAUNCH_REFERENCE, size: bytes.length, sha256: crypto.createHash('sha256').update(bytes).digest('hex') }, fetchImpl: async url => ({ ok: url === LAUNCH_REFERENCE.url, status: 200, body: Readable.toWeb(Readable.from(bytes)) }), inspectPackage: () => ({ format: 'ps5-fih-debug-package', validation: { structurallyValid: true, validationLevel: 'fih-cnt-structural-v3', contentId: LAUNCH_REFERENCE.contentId, imageCount: 0, imageKey: { profile: 'opaque-filled-0x800' } } }), registrar: async manifest => { registrations.push(manifest); return { packageSetId: 1110, titleId: 43 }; }, }); return { root, bytes, registrations, service }; } test('imports only the exact hash-pinned official websrv launch reference', 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.launchVerified, false); assert.equal(result.installAuthorized, false); assert.deepEqual(fs.readFileSync(result.absolutePath), f.bytes); assert.equal(f.registrations[0].launchReferenceProfile, 'websrv-launcher-1afd476'); assert.equal(f.registrations[0].components[0].provenance[0].provider, 'ps5-payload-dev/websrv'); const proven = f.service.recordInstallEvidence({ operationId: 'launcher-op-1', source: 'post-install-console-scan', observed_at: Date.now() }); assert.equal(proven.installTrust.status, 'post-scan-proven'); assert.equal(proven.launchVerified, false); assert.equal(proven.nextAction, 'manual-launch-required'); }); test('rejects launch-reference hash drift and profile drift without publishing', async t => { const f = fixture(); t.after(() => fs.rmSync(f.root, { recursive: true, force: true })); const badHash = createPs5LaunchReferencePackageService({ outputRoot: f.root, stateFile: path.join(f.root, 'bad-hash.json'), descriptor: { ...LAUNCH_REFERENCE, 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_LAUNCH_REFERENCE_HASH'); assert.equal(fs.existsSync(badHash.targetPath()), false); const badProfile = createPs5LaunchReferencePackageService({ outputRoot: f.root, stateFile: path.join(f.root, 'bad-profile.json'), descriptor: { ...LAUNCH_REFERENCE, 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: LAUNCH_REFERENCE.contentId, imageCount: 1, imageKey: { profile: 'experimental-kstuff-rsa2048-native-stride' } } }), registrar: async () => ({}) }); await assert.rejects(badProfile.importPackage(), error => error.code === 'PS5_LAUNCH_REFERENCE_PROFILE'); assert.equal(fs.existsSync(badProfile.targetPath()), false); }); test('launch-reference routes use a separate exact confirmation and never infer launch from installation', () => { const registry = fs.readFileSync('src/server/create-registry.js', 'utf8'); assert.match(registry, /ps5-native-packages:launch-reference-status[\s\S]*classification: 'read-only'/); assert.match(registry, /ps5-native-packages:launch-reference-import[\s\S]*classification: 'mutating'/); assert.match(registry, /ps5-native-packages:launch-reference-restore[\s\S]*classification: 'destructive'[\s\S]*INSTALL PS5 LAUNCH REFERENCE/); assert.match(registry, /ps5-native-packages:launch-reference-restore-verify[\s\S]*launchVerified: false[\s\S]*manual-launch-required/); }); test('launch-reference descriptor is pinned to the inspected official artifact', () => { assert.equal(LAUNCH_REFERENCE.revision, '1afd476c5044d68df4e45dc773769e5de3b2cdd6'); assert.equal(LAUNCH_REFERENCE.size, 18_168_015); assert.equal(LAUNCH_REFERENCE.sha256, 'c737b79be8c47b89b2e4e38ca404cdad6d30c0ff659aaf25c7e9ea1368341434'); assert.equal(LAUNCH_REFERENCE.contentId, 'IV9999-FAKE00000_00-HOMEBREWLOADER01'); }); test('launch-reference UI and both bridges expose the guarded three-step flow', () => { 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 html = fs.readFileSync('renderer/index.html', 'utf8'); const css = fs.readFileSync('renderer/styles/ps5-native-packages.css', 'utf8'); for (const source of [preload, web]) { assert.match(source, /ps5LaunchReference/); assert.match(source, /ps5-native-packages:launch-reference-/); } assert.match(main, /PS5_LAUNCH_REFERENCE_SERVER_REQUIRED/); assert.match(html, /ps5-launch-reference-import/); assert.match(modal, /INSTALL PS5 LAUNCH REFERENCE/); assert.match(modal, /ps5LaunchReference\('restore-verify'/); assert.match(modal, /launch is not yet proven/); assert.match(css, /ps5-launch-reference/); }); test('registers the validated FAKE homebrew title as PS5 without loosening global title inference', async t => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-ps5-launch-title-')); database.configure({ dataDir: path.join(root, 'db'), logger: { info() {}, warn() {}, error() {} } }); await database.initialize(); t.after(() => { database.close(); fs.rmSync(root, { recursive: true, force: true }); }); const outputRoot = path.join(root, 'vault'); const folder = path.join(outputRoot, 'launch-reference'); fs.mkdirSync(folder, { recursive: true }); const pkg = path.join(folder, LAUNCH_REFERENCE.filename); const bytes = Buffer.from('validated-launch-reference'); fs.writeFileSync(pkg, bytes); const manifest = { schemaVersion: 1, kind: 'chimera.ps5-native-package.v1', launchReferenceProfile: 'websrv-launcher-1afd476', createdAt: Date.now(), title: { platform: 'ps5', titleId: LAUNCH_REFERENCE.titleId, name: LAUNCH_REFERENCE.title }, packageFormat: { container: 'FIH', debug: true, retail: false }, components: [{ id: 'base', type: 'base', version: LAUNCH_REFERENCE.version, contentId: LAUNCH_REFERENCE.contentId, size: bytes.length, sha256: crypto.createHash('sha256').update(bytes).digest('hex'), absolutePath: pkg, required: true, order: 1, provenance: [] }], dependencies: [], recipe: { installOrder: [{ componentId: 'base', order: 1 }] }, }; const result = registerPs5NativePackageManifest({ db: database, outputRoot, manifest, source: 'official-upstream-release-artifact', variantKey: 'websrv-launch-reference' }); assert.ok(result.packageSetId); assert.equal(database.runQuery("SELECT platform FROM titles WHERE title_id='FAKE00000'")[0].platform, 'ps5'); assert.equal(database.runQuery("SELECT COUNT(*) AS count FROM titles WHERE title_id='FAKE00000'")[0].count, 1); });