Preserve uncertain remote commits and destructive source-cleanup requirements across cancellation, persistence failures, retries, and restart recovery. Revalidate account availability after admission waits and prevent late upload results from bypassing cancellation state. Strengthen release argument, CI tag, source allowlist, and secret scanning gates. Run the Electron smoke suite in a fully hidden offscreen harness that cannot reveal, focus, or elevate native windows.
This commit is contained in:
@@ -41,6 +41,26 @@ function verify(stage, version = currentVersion, sourceOnly = true) {
|
||||
});
|
||||
}
|
||||
|
||||
function verifyTracked(stage) {
|
||||
return spawnSync(process.execPath, [
|
||||
'scripts/verify-public-release.mjs',
|
||||
'--source-only',
|
||||
'--tracked',
|
||||
'--package-version'
|
||||
], {
|
||||
cwd: stage,
|
||||
encoding: 'utf8'
|
||||
});
|
||||
}
|
||||
|
||||
function git(stage, args) {
|
||||
const result = spawnSync('git', args, {
|
||||
cwd: stage,
|
||||
encoding: 'utf8'
|
||||
});
|
||||
assert.equal(result.status, 0, result.error?.message || result.stderr || result.stdout);
|
||||
}
|
||||
|
||||
test('public release verifier accepts only the exact source manifest and target version', (t) => {
|
||||
const stage = createStage();
|
||||
t.after(() => fs.rmSync(stage, { recursive: true, force: true }));
|
||||
@@ -81,6 +101,87 @@ test('public source verification runs against the actual checkout at its package
|
||||
assert.match(result.stdout, /layout=exact/);
|
||||
});
|
||||
|
||||
test('public release verifier rejects known credential patterns in approved text files', async (t) => {
|
||||
const stage = createStage();
|
||||
t.after(() => fs.rmSync(stage, { recursive: true, force: true }));
|
||||
const target = path.join(stage, 'README.md');
|
||||
const original = fs.readFileSync(target, 'utf8');
|
||||
const assignment = (name, value) => `${name} = "${value}"`;
|
||||
const fixtures = [
|
||||
['access token', ['gh', 'p_'].join('') + 'SYNTHETICNOTREAL'.padEnd(36, '0')],
|
||||
['fine-grained access token', ['github', 'pat'].join('_') + '_' + 'A'.repeat(82)],
|
||||
['forge token assignment', assignment(['access', 'token'].join('_'), 'a'.repeat(40))],
|
||||
['npm token', ['npm', ''].join('_') + 'A'.repeat(36)],
|
||||
['Slack token', ['xox', 'b'].join('') + '-' + ['1'.repeat(12), '2'.repeat(12), 'A'.repeat(24)].join('-')],
|
||||
['JWT', ['eyJ', 'hbGciOiJIUzI1NiJ9'].join('') + '.' + ['eyJ', 'zdWIiOiIxMjM0NTY3ODkwIn0'].join('') + '.signaturevalue'],
|
||||
['Bearer token', ['Bear', 'er '].join('') + 'A'.repeat(32)],
|
||||
['password assignment', assignment(['pass', 'word'].join(''), 'CorrectHorseBatteryStaple')],
|
||||
['API key assignment', assignment(['api', 'key'].join('_'), 'A1b2C3d4E5f6G7h8')],
|
||||
['unquoted password assignment', ['pass', 'word'].join('') + ': CorrectHorseBatteryStaple'],
|
||||
['unquoted API key assignment', ['api', 'key'].join('_') + ': abcdefghijklmnop'],
|
||||
['cookie assignment', assignment(['cook', 'ie'].join(''), 'session-value-123456789')],
|
||||
['session assignment', assignment(['sess', 'ion'].join(''), 'session-value-123456789')],
|
||||
['private key', ['-----BEGIN ', 'PRIVATE KEY-----'].join('') + '\nSYNTHETICNOTAKEY\n-----END PRIVATE KEY-----'],
|
||||
['secret', ['aws', '_secret_access_key'].join('') + ' = ' + 'SYNTHETICNOTREALSECRET'.padEnd(40, '0')]
|
||||
];
|
||||
|
||||
for (const [name, fixture] of fixtures) {
|
||||
await t.test(name, () => {
|
||||
fs.writeFileSync(target, `${original}\n${fixture}\n`);
|
||||
const result = verify(stage);
|
||||
assert.equal(result.status, 1, result.stderr);
|
||||
assert.match(result.stderr, /README\.md\tcredential-pattern/);
|
||||
fs.writeFileSync(target, original);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test('public release verifier rejects realistic credentials inside approved test files', (t) => {
|
||||
const stage = createStage();
|
||||
t.after(() => fs.rmSync(stage, { recursive: true, force: true }));
|
||||
const target = path.join(stage, 'tests', 'account-status.test.js');
|
||||
const original = fs.readFileSync(target, 'utf8');
|
||||
const fixture = ['pass', 'word'].join('') + ': CorrectHorseBatteryStaple';
|
||||
fs.writeFileSync(target, `${original}\n${fixture}\n`);
|
||||
|
||||
const result = verify(stage);
|
||||
assert.equal(result.status, 1, result.stderr);
|
||||
assert.match(result.stderr, /tests\/account-status\.test\.js\tcredential-pattern/);
|
||||
});
|
||||
|
||||
test('--tracked validates tracked source and every untracked Electron build input', (t) => {
|
||||
const stage = createStage();
|
||||
t.after(() => fs.rmSync(stage, { recursive: true, force: true }));
|
||||
git(stage, ['init', '--quiet']);
|
||||
git(stage, ['add', '--all']);
|
||||
|
||||
fs.writeFileSync(path.join(stage, 'tests', 'unexpected.json'), '{}');
|
||||
fs.writeFileSync(path.join(stage, 'tests', 'untracked.json'), '{}');
|
||||
fs.writeFileSync(path.join(stage, 'renderer', 'private-config.js'), 'module.exports = {};');
|
||||
git(stage, ['add', '--', 'tests/unexpected.json']);
|
||||
const result = verifyTracked(stage);
|
||||
assert.equal(result.status, 1, result.stderr);
|
||||
assert.match(result.stderr, /tests\/unexpected\.json\tsource-layout-allowlist/);
|
||||
assert.match(result.stderr, /renderer\/private-config\.js\tsource-layout-allowlist/);
|
||||
assert.doesNotMatch(result.stderr, /tests\/untracked\.json/);
|
||||
});
|
||||
|
||||
test('public release verifier detects private updater endpoints hidden by string concatenation', (t) => {
|
||||
const stage = createStage();
|
||||
t.after(() => fs.rmSync(stage, { recursive: true, force: true }));
|
||||
const target = path.join(stage, 'README.md');
|
||||
const original = fs.readFileSync(target, 'utf8');
|
||||
const hiddenEndpoint = String.fromCharCode(
|
||||
99, 111, 110, 115, 116, 32, 104, 111, 115, 116, 32, 61, 32, 39, 103, 105, 116, 39, 32, 43, 32, 39, 46,
|
||||
50, 52, 45, 39, 32, 43, 32, 39, 109, 117, 115, 105, 99, 46, 100, 101, 39, 59
|
||||
);
|
||||
fs.writeFileSync(target, `${original}\n${hiddenEndpoint}\n`);
|
||||
|
||||
const result = verify(stage);
|
||||
assert.equal(result.status, 1, result.stderr);
|
||||
assert.match(result.stderr, /README\.md\tupdater-endpoint-scope/);
|
||||
});
|
||||
|
||||
test('public release verifier requires and validates every approved screenshot', (t) => {
|
||||
const stage = createStage();
|
||||
t.after(() => fs.rmSync(stage, { recursive: true, force: true }));
|
||||
|
||||
Reference in New Issue
Block a user