mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
fix(server): keep debug-log timestamps server-owned and send nosniff
The voice debug log writes the server's timestamp after the client's record, so a record can no longer replace loggedAt. The dev and preview servers also send X-Content-Type-Options: nosniff with their shared browser headers. From the findings in #710. Co-authored-by: Sunil <[email protected]> Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
98b8c6c581
commit
bbf4976f5e
5 files changed
+29
-3
No files matched your search
@@ -391,8 +391,8 @@ test('the debug-log sink stays bounded, rate limited, and quiet about failures',
|
||||
error: 'Failed to write Realtime debug log',
|
||||
});
|
||||
|
||||
// The limiter is always on, unlike the opt-in one the cost-bearing routes
|
||||
// share: 120/min per IP, far above what a voice session writes.
|
||||
// This limiter has no opt-out, unlike the one the cost-bearing routes share:
|
||||
// 120/min per IP, far above what a voice session writes.
|
||||
let limited = null;
|
||||
let accepted = 0;
|
||||
for (let n = 0; n < 130 && !limited; n += 1) {
|
||||
@@ -415,6 +415,24 @@ test('the debug-log sink stays bounded, rate limited, and quiet about failures',
|
||||
assert.ok(lines.every((line) => JSON.parse(line).loggedAt));
|
||||
});
|
||||
|
||||
test('a debug-log record cannot supply its own timestamp', async (t) => {
|
||||
const sourceRoot = root(t);
|
||||
const handler = install(openAiRealtimeProxy({ sourceRoot })).get(
|
||||
'/api/realtime/debug-log',
|
||||
);
|
||||
const before = Date.now();
|
||||
const response = await request(handler, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ loggedAt: '1999-01-01T00:00:00.000Z', note: 'x' }),
|
||||
});
|
||||
assert.equal(response.status, 204);
|
||||
const file = path.join(sourceRoot, '.gev-logs/realtime-conversations.jsonl');
|
||||
const [line] = readFileSync(file, 'utf8').split('\n').filter(Boolean);
|
||||
const record = JSON.parse(line);
|
||||
assert.equal(record.note, 'x');
|
||||
assert.ok(Date.parse(record.loggedAt) >= before - 1000);
|
||||
});
|
||||
|
||||
test('an oversized debug-log request receives the fixed error response', async (t) => {
|
||||
const handler = install(openAiRealtimeProxy({ sourceRoot: root(t) })).get(
|
||||
'/api/realtime/debug-log',
|
||||
|
||||
@@ -19,6 +19,7 @@ test('explicit build inputs preserve browser-only defines, plugin order and loop
|
||||
assert.ok(config.server.fs.deny.includes('**/ENVIRONMENT'));
|
||||
assert.ok(config.server.fs.deny.includes('.env.*'));
|
||||
assert.equal(config.server.headers['X-Frame-Options'], 'DENY');
|
||||
assert.equal(config.server.headers['X-Content-Type-Options'], 'nosniff');
|
||||
const csp = config.server.headers['Content-Security-Policy'];
|
||||
assert.equal(csp, BROWSER_CSP);
|
||||
for (const directive of [
|
||||
|
||||
Reference in new issue
Block a user