Update
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdtemp, readFile, rm } from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import zlib from 'node:zlib';
|
||||
import diagnosticsModule from '../src/main/diagnostics-service.cjs';
|
||||
|
||||
const { DiagnosticsService } = diagnosticsModule;
|
||||
|
||||
function unzipLocalEntries(buffer) {
|
||||
const entries = new Map();
|
||||
let offset = 0;
|
||||
while (offset + 4 <= buffer.length && buffer.readUInt32LE(offset) === 0x04034b50) {
|
||||
const method = buffer.readUInt16LE(offset + 8);
|
||||
const compressedSize = buffer.readUInt32LE(offset + 18);
|
||||
const nameLength = buffer.readUInt16LE(offset + 26);
|
||||
const extraLength = buffer.readUInt16LE(offset + 28);
|
||||
const nameStart = offset + 30;
|
||||
const dataStart = nameStart + nameLength + extraLength;
|
||||
const name = buffer.subarray(nameStart, nameStart + nameLength).toString('utf8');
|
||||
const compressed = buffer.subarray(dataStart, dataStart + compressedSize);
|
||||
entries.set(name, method === 8 ? zlib.inflateRawSync(compressed) : compressed);
|
||||
offset = dataStart + compressedSize;
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
test('writes structured local diagnostics and exports a secret-free support bundle', async (t) => {
|
||||
const root = await mkdtemp(path.join(os.tmpdir(), 'forgeflow-diagnostics-'));
|
||||
t.after(() => rm(root, { recursive: true, force: true }));
|
||||
const secret = ['gitea', 'TEST', 'ONLY', 'ULTRA', 'SECRET', '1234567890'].join('_');
|
||||
const service = new DiagnosticsService({
|
||||
userDataPath: root,
|
||||
appInfo: { name: 'ForgeFlow', version: '0.3.0-test' },
|
||||
secretProvider: () => [secret],
|
||||
preferencesProvider: () => ({ diagnosticsEnabled: true, diagnosticLevel: 'debug', logRetentionDays: 14, maxLogFileMb: 8 })
|
||||
});
|
||||
await service.initialize();
|
||||
await service.error('test.failure', {
|
||||
authorization: `token ${secret}`,
|
||||
password: 'unsafe-password',
|
||||
message: `request failed with ${secret}`,
|
||||
path: path.join(os.homedir(), 'private', 'repository')
|
||||
});
|
||||
await service.flush();
|
||||
|
||||
const status = await service.getStatus();
|
||||
assert.equal(status.enabled, true);
|
||||
assert.ok(status.fileCount >= 1);
|
||||
const raw = (await Promise.all((await service.listLogFiles()).map((file) => readFile(file.path, 'utf8')))).join('\n');
|
||||
assert.doesNotMatch(raw, new RegExp(secret));
|
||||
assert.doesNotMatch(raw, /unsafe-password/);
|
||||
assert.doesNotMatch(raw, new RegExp(os.homedir().replace(/[.*+?^${}()|[\]\\]/g, '\\$&')));
|
||||
|
||||
const destination = path.join(root, 'support.zip');
|
||||
const result = await service.exportSupportBundle({
|
||||
destinationPath: destination,
|
||||
privacyMode: 'strict',
|
||||
publicState: { gitea: { baseUrl: 'https://gitea.example.test', hasToken: true, encryptedToken: 'ciphertext' }, preferences: {} },
|
||||
repositories: [{ id: 1, fullName: 'jens/private-repo', localPath: path.join(os.homedir(), 'private-repo'), localStatus: { head: 'a'.repeat(40), branch: { head: 'main' }, counts: {}, clean: true } }],
|
||||
operations: [{ repository: 'jens/private-repo', status: 'failed', runnerLog: `Authorization: token ${secret}` }],
|
||||
preflight: { checks: [] }
|
||||
});
|
||||
assert.equal(service.isKnownBundlePath(result.path), true);
|
||||
const entries = unzipLocalEntries(await readFile(destination));
|
||||
const bundleText = [...entries.values()].map((value) => value.toString('utf8')).join('\n');
|
||||
assert.doesNotMatch(bundleText, new RegExp(secret));
|
||||
assert.doesNotMatch(bundleText, /ciphertext|unsafe-password|jens\/private-repo/);
|
||||
assert.match(entries.get('manifest.json').toString(), /"containsSecrets": false/);
|
||||
assert.match(entries.get('repositories-sanitized.json').toString(), /fullname-[a-f0-9]{12}/);
|
||||
|
||||
const cleared = await service.clear();
|
||||
assert.ok(cleared.fileCount >= 1, 'clear writes a new safe session marker');
|
||||
});
|
||||
Reference in New Issue
Block a user