import fs from 'node:fs/promises'; import assert from 'node:assert/strict'; import { randomUUID } from 'node:crypto'; const fixture = JSON.parse(await fs.readFile('C:/laragon/data/sgf-tempo/secrets/browser-fixture.json', 'utf8')); const base = 'http://127.0.0.1:8001'; function client() { const cookies = new Map(); let csrf = ''; let context = ''; return { async request(path, method = 'GET', body, key = randomUUID(), token = context) { const headers = { Accept: 'application/json', 'Content-Type': 'application/json', Cookie: [...cookies].map(([k,v]) => `${k}=${v}`).join('; '), 'X-CSRF-TOKEN': csrf, 'X-SGF-Context': token, 'Idempotency-Key': key }; const response = await fetch(base + path, { method, headers, ...(body === undefined ? {} : { body: JSON.stringify(body) }) }); for (const cookie of response.headers.getSetCookie()) { const pair = cookie.split(';', 1)[0], split = pair.indexOf('='); cookies.set(pair.slice(0, split), pair.slice(split + 1)); } const data = await response.json().catch(() => ({})); if (data.csrf) csrf = data.csrf; if (data.context?.token) context = data.context.token; return { status: response.status, data }; }, async login(email) { await this.request('/api/session'); assert.equal((await this.request('/api/login', 'POST', { email, password: fixture.password })).status, 200); await this.select(); }, async select(unit = fixture.unit) { const result = await this.request('/api/context', 'POST', { tenant_id: fixture.tenant, company_id: fixture.company, unit_id: unit }); assert.equal(result.status, 200); return result.data.context.token; } }; } const manager = client(), reader = client(); await manager.login('gestor@example.test'); await reader.login('consulta@example.test'); async function create(area, data) { const result = await manager.request('/api/a/' + area, 'POST', data); assert.equal(result.status, 201); return result.data.id; } const customer = await create('clients', { name: 'Cliente fotografia B1 HTTP' }); const service = await create('services', { name: 'Serviço fotografia B1 HTTP' }); const source = await create('service_drafts', { client_id: customer, lines: [{ service_id: service, quantity: '1.25', unit_price: '0.00000001' }] }); const draft = await create('billing_drafts', { source_id: source }); const endpoint = `/api/b1/billing-drafts/${draft}/confirm-internal`, record = `/api/a/billing_drafts/${draft}`; assert.equal((await reader.request(endpoint, 'POST', { version: 1 })).status, 403); assert.equal((await manager.request(endpoint, 'POST', { version: 2 })).status, 409); const oldToken = await manager.select(); await manager.select(null); assert.equal((await manager.request(endpoint, 'POST', { version: 1 }, randomUUID(), oldToken)).status, 409); await manager.select(); const key = randomUUID(), first = await manager.request(endpoint, 'POST', { version: 1 }, key); assert.equal(first.status, 200); const replay = await manager.request(endpoint, 'POST', { version: 1 }, key); assert.equal(replay.status, 200); assert.equal(replay.data.id, first.data.id); assert.equal(replay.data.replayed, true); assert.equal((await manager.request(endpoint, 'POST', { version: 2 }, key)).status, 409); const before = (await manager.request(record)).data.confirmation; assert.equal(before.snapshot.data.currency, null); assert.equal(before.snapshot.base_amount, '0.0000000125'); for (const pending of ['currency_missing', 'tax_rule_pending', 'accounting_rule_pending', 'accounts_pending', 'recognition_pending']) assert.ok(before.snapshot.pending[pending]); assert.equal((await manager.request(`/api/a/clients/${customer}`, 'PATCH', { name: 'Cliente alterado após confirmação HTTP', version: 1 })).status, 200); assert.equal((await manager.request(`/api/a/services/${service}`, 'PATCH', { name: 'Serviço alterado após confirmação HTTP', version: 1 })).status, 200); assert.deepEqual((await manager.request(record)).data.confirmation, before); assert.equal((await manager.request(record, 'PATCH', { version: 1, reload_source: true })).status, 409); assert.equal((await reader.request(record)).status, 200); assert.equal(before.event.type, 'b1.billing_draft.confirmed_internal'); assert.equal(before.event.state, 'captured'); assert.equal(before.snapshot.fiscal_status, 'not_issued'); assert.equal(before.snapshot.accounting_status, 'blocked_pending'); await manager.request('/api/logout', 'POST'); await reader.request('/api/logout', 'POST'); await fs.writeFile('docs/proofs/b1-http-results.json', JSON.stringify({ database: 'sgf_tempo_test', real_synthetic_login: true, results: ['Confirmation authorized; reader denied 403.', 'Old context and version denied 409.', 'Identical command recovers confirmation; different content conflicts 409.', 'Snapshot unchanged after client/service edits.', 'Confirmed draft edit denied 409; reader consultation 200.', 'Currency remains unknown, tax/accounts/recognition pending; captured, not issued or accounted.'] }, null, 2)); console.log('B1 isolated HTTP proof passed; no credentials displayed.');