'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('fs'); const os = require('os'); const path = require('path'); const { SecretsStore } = require('../../src/security/secrets-store'); const { hashPassword, verifyPassword } = require('../../src/security/passwords'); const { mountedRoots, resolveAllowedPath } = require('../../src/platform/data-paths'); const { redact } = require('../../src/platform/logger'); test('secrets are encrypted at rest and passwords use scrypt', async () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'porkfolio-security-')); const store = new SecretsStore({ filePath: path.join(root, 'secrets.json'), keyFile: path.join(root, 'master.key') }); store.set('ftp.password', 'top-secret-value'); assert.equal(store.get('ftp.password'), 'top-secret-value'); assert.equal(fs.readFileSync(path.join(root, 'secrets.json'), 'utf8').includes('top-secret-value'), false); const encoded = await hashPassword('een-lang-wachtwoord'); assert.equal(await verifyPassword('een-lang-wachtwoord', encoded), true); assert.equal(await verifyPassword('verkeerd-wachtwoord', encoded), false); }); test('path allowlist rejects traversal and redaction removes sensitive values', () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'porkfolio-path-')); const inside = path.join(root, 'export', 'file.bin'); assert.equal(resolveAllowedPath(inside, [root]), inside); assert.throws(() => resolveAllowedPath(path.join(root, '..', 'outside.txt'), [root]), /buiten/); assert.deepEqual(redact({ user: 'jens', password: 'secret', nested: { token: 'abc' } }), { user: 'jens', password: '[REDACTED]', nested: { token: '[REDACTED]' } }); }); test('mounted server roots use the same absolute representation as the allowlist', () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-mounted-roots-')); const existsSync = fs.existsSync; fs.existsSync = value => String(value) === '/downloads' || existsSync(value); try { const roots = mountedRoots(root); assert.ok(roots.includes(path.resolve('/downloads'))); assert.ok(roots.every(value => path.isAbsolute(value))); } finally { fs.existsSync = existsSync; } });