fix: 2026-06-04 audit pass — README, USB pack, multi-area fixes

WS ticket dashboard auth, builder universal signing/size limits/fusion obfuscation/dropper bundles, Path Tracer WireGuard topology, SessionGate degraded mode and download timeouts, server bootstrap (data dir, cloudflared dedupe, config port precedence), agent mesh/miner/spread fixes. README refreshed; usb bundle repacked; PROBLEMS.md audit log updated.
This commit is contained in:
AetherForge
2026-06-04 20:41:44 -07:00
parent 6bfce5d5ab
commit 8466c7aa9b
101 changed files with 3369 additions and 1054 deletions

View File

@@ -22,6 +22,7 @@ describe('api client', () => {
beforeEach(() => {
sessionStorage.clear();
localStorage.clear();
fetchMock = vi.fn();
vi.stubGlobal('fetch', fetchMock);
});
@@ -38,6 +39,7 @@ describe('api client', () => {
function expectAuthHeaders(init: RequestInit) {
const headers = init.headers as Record<string, string>;
expect(headers.Authorization).toBe(`Basic ${btoa('user:pass')}`);
expect(headers['X-AetherForge-Client']).toBe('dashboard');
}
it('sends JSON Content-Type and auth on listAgents', async () => {
@@ -69,6 +71,16 @@ describe('api client', () => {
const headers = lastFetch().init.headers as Record<string, string>;
expect(headers.Authorization).toBeUndefined();
expect(headers['X-AetherForge-Client']).toBe('dashboard');
});
it('clears stored auth on 401 API response', async () => {
setStoredAuth('user', 'pass');
fetchMock.mockResolvedValueOnce(textResponse('Unauthorized', 401));
await expect(api.listAgents()).rejects.toThrow('API error 401');
expect(sessionStorage.getItem('aetherforge_auth')).toBeNull();
expect(localStorage.getItem('aetherforge_auth')).toBeNull();
});
it('getAgentStats appends limit query param', async () => {
@@ -111,6 +123,18 @@ describe('api client', () => {
expect(url).toBe('/api/v1/builder/build');
expect(init.method).toBe('POST');
expect(init.body).toBe(JSON.stringify(req));
expect(init.signal).toBeDefined();
});
it('buildAgent surfaces server error from JSON body', async () => {
const req = { fusion_enabled: false, wallet: '4' + 'A'.repeat(94) } as Parameters<typeof api.buildAgent>[0];
fetchMock.mockResolvedValueOnce({
ok: false,
status: 500,
text: async () => JSON.stringify({ success: false, error: 'compile failed (garble): OOM' }),
});
await expect(api.buildAgent(req)).rejects.toThrow('compile failed (garble): OOM');
});
it('buildAgent rejects fusion without prep file', async () => {