const { test } = require('node:test'); const assert = require('node:assert/strict'); const { execFileSync, spawnSync } = require('node:child_process'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const ROOT = path.join(__dirname, '..'); const SCRIPT = path.join(ROOT, 'scripts', 'build-deb.sh'); const pkg = require('../package.json'); // Builds the .deb with a restrictive umask (npm stubbed out — dependency // installation is irrelevant to permissions and would need the network) and // asserts the payload is world-readable: with umask 077 and no explicit // normalization, `stoke` would be unusable for non-root after install. test('payload files are world-readable even when built with umask 077', () => { const bin = fs.mkdtempSync(path.join(os.tmpdir(), 'stoke-build-test-')); fs.writeFileSync(path.join(bin, 'npm'), '#!/usr/bin/env bash\nexit 0\n', { mode: 0o755 }); const distDir = path.join(ROOT, 'dist'); const deb = path.join(distDir, `stoke_${pkg.version}_all.deb`); const distExisted = fs.existsSync(distDir); try { const res = spawnSync('bash', ['-c', 'umask 077 && exec bash "$1"', 'bash', SCRIPT], { encoding: 'utf8', env: { ...process.env, PATH: `${bin}:${process.env.PATH}` }, }); assert.equal(res.status, 0, res.stderr); const listing = execFileSync('bash', ['-c', 'dpkg-deb --fsys-tarfile "$1" | tar -tv', 'bash', deb], { encoding: 'utf8', }); const entries = listing.trim().split('\n').filter((l) => l.includes('/usr/')); assert.ok(entries.length > 0, 'payload listing must not be empty'); for (const line of entries) { const perms = line.split(/\s+/)[0]; if (perms.startsWith('l')) continue; // symlink target perms are irrelevant assert.equal(perms[7], 'r', `not world-readable: ${line}`); assert.equal(perms[5], '-', `group-writable: ${line}`); assert.equal(perms[8], '-', `other-writable: ${line}`); } } finally { fs.rmSync(bin, { recursive: true, force: true }); fs.rmSync(deb, { force: true }); if (!distExisted) fs.rmSync(distDir, { recursive: true, force: true }); } });