Skip to content

Commit 6717b08

Browse files
authored
feat: Verify server header. (#279)
1 parent 04523a5 commit 6717b08

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

src/Client.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Event } from './Event.js';
33
import type { EventCandidate } from './EventCandidate.js';
44
import type { EventType } from './EventType.js';
55
import { isCloudEvent } from './isCloudEvent.js';
6+
import { isValidServerHeader } from './isValidServerHeader.js';
67
import { readNdJsonStream } from './ndjson/readNdJsonStream.js';
78
import type { ObserveEventsOptions } from './ObserveEventsOptions.js';
89
import type { Precondition } from './Precondition.js';
@@ -49,6 +50,10 @@ class Client {
4950
method: 'get',
5051
});
5152

53+
if (!isValidServerHeader(response)) {
54+
throw new Error('Server must be EventSourcingDB.');
55+
}
56+
5257
if (response.status !== 200) {
5358
throw new Error(`Failed to ping, got HTTP status code '${response.status}', expected '200'.`);
5459
}
@@ -77,6 +82,10 @@ class Client {
7782
},
7883
});
7984

85+
if (!isValidServerHeader(response)) {
86+
throw new Error('Server must be EventSourcingDB.');
87+
}
88+
8089
if (response.status !== 200) {
8190
throw new Error(
8291
`Failed to verify API token, got HTTP status code '${response.status}', expected '200'.`,
@@ -115,6 +124,10 @@ class Client {
115124
}),
116125
});
117126

127+
if (!isValidServerHeader(response)) {
128+
throw new Error('Server must be EventSourcingDB.');
129+
}
130+
118131
if (response.status !== 200) {
119132
throw new Error(
120133
`Failed to write events, got HTTP status code '${response.status}', expected '200'.`,
@@ -174,6 +187,14 @@ class Client {
174187
signal: combinedSignal,
175188
});
176189

190+
if (!isValidServerHeader(response)) {
191+
const serverHeader = response.headers.get('Server');
192+
if (!serverHeader) {
193+
throw new Error('Server must be EventSourcingDB, but Server header is missing.');
194+
}
195+
throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`);
196+
}
197+
177198
if (response.status !== 200) {
178199
throw new Error(
179200
`Failed to read events, got HTTP status code '${response.status}', expected '200'.`,
@@ -239,6 +260,14 @@ class Client {
239260
signal: combinedSignal,
240261
});
241262

263+
if (!isValidServerHeader(response)) {
264+
const serverHeader = response.headers.get('Server');
265+
if (!serverHeader) {
266+
throw new Error('Server must be EventSourcingDB, but Server header is missing.');
267+
}
268+
throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`);
269+
}
270+
242271
if (response.status !== 200) {
243272
throw new Error(
244273
`Failed to run EventQL query, got HTTP status code '${response.status}', expected '200'.`,
@@ -314,6 +343,14 @@ class Client {
314343
signal: combinedSignal,
315344
});
316345

346+
if (!isValidServerHeader(response)) {
347+
const serverHeader = response.headers.get('Server');
348+
if (!serverHeader) {
349+
throw new Error('Server must be EventSourcingDB, but Server header is missing.');
350+
}
351+
throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`);
352+
}
353+
317354
if (response.status !== 200) {
318355
throw new Error(
319356
`Failed to observe events, got HTTP status code '${response.status}', expected '200'.`,
@@ -371,6 +408,10 @@ class Client {
371408
}),
372409
});
373410

411+
if (!isValidServerHeader(response)) {
412+
throw new Error('Server must be EventSourcingDB.');
413+
}
414+
374415
if (response.status !== 200) {
375416
throw new Error(
376417
`Failed to register event schema, got HTTP status code '${response.status}', expected '200'.`,
@@ -411,6 +452,14 @@ class Client {
411452
signal: combinedSignal,
412453
});
413454

455+
if (!isValidServerHeader(response)) {
456+
const serverHeader = response.headers.get('Server');
457+
if (!serverHeader) {
458+
throw new Error('Server must be EventSourcingDB, but Server header is missing.');
459+
}
460+
throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`);
461+
}
462+
414463
if (response.status !== 200) {
415464
throw new Error(
416465
`Failed to read subjects, got HTTP status code '${response.status}', expected '200'.`,
@@ -460,6 +509,10 @@ class Client {
460509
}),
461510
});
462511

512+
if (!isValidServerHeader(response)) {
513+
throw new Error('Server must be EventSourcingDB.');
514+
}
515+
463516
if (response.status !== 200) {
464517
throw new Error(
465518
`Failed to read event type, got HTTP status code '${response.status}', expected '200'.`,
@@ -504,6 +557,14 @@ class Client {
504557
signal: combinedSignal,
505558
});
506559

560+
if (!isValidServerHeader(response)) {
561+
const serverHeader = response.headers.get('Server');
562+
if (!serverHeader) {
563+
throw new Error('Server must be EventSourcingDB, but Server header is missing.');
564+
}
565+
throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`);
566+
}
567+
507568
if (response.status !== 200) {
508569
throw new Error(
509570
`Failed to read event types, got HTTP status code '${response.status}', expected '200'.`,

src/isValidServerHeader.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const isValidServerHeader = (response: Response): boolean => {
2+
const serverHeader = response.headers.get('Server');
3+
4+
if (!serverHeader) {
5+
return false;
6+
}
7+
8+
if (!serverHeader.startsWith('EventSourcingDB/')) {
9+
return false;
10+
}
11+
12+
return true;
13+
};
14+
15+
export { isValidServerHeader };

0 commit comments

Comments
 (0)