diff --git a/src/Client.ts b/src/Client.ts index 93779bb..75d8115 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -3,6 +3,7 @@ import type { Event } from './Event.js'; import type { EventCandidate } from './EventCandidate.js'; import type { EventType } from './EventType.js'; import { isCloudEvent } from './isCloudEvent.js'; +import { isValidServerHeader } from './isValidServerHeader.js'; import { readNdJsonStream } from './ndjson/readNdJsonStream.js'; import type { ObserveEventsOptions } from './ObserveEventsOptions.js'; import type { Precondition } from './Precondition.js'; @@ -49,6 +50,10 @@ class Client { method: 'get', }); + if (!isValidServerHeader(response)) { + throw new Error('Server must be EventSourcingDB.'); + } + if (response.status !== 200) { throw new Error(`Failed to ping, got HTTP status code '${response.status}', expected '200'.`); } @@ -77,6 +82,10 @@ class Client { }, }); + if (!isValidServerHeader(response)) { + throw new Error('Server must be EventSourcingDB.'); + } + if (response.status !== 200) { throw new Error( `Failed to verify API token, got HTTP status code '${response.status}', expected '200'.`, @@ -115,6 +124,10 @@ class Client { }), }); + if (!isValidServerHeader(response)) { + throw new Error('Server must be EventSourcingDB.'); + } + if (response.status !== 200) { throw new Error( `Failed to write events, got HTTP status code '${response.status}', expected '200'.`, @@ -174,6 +187,14 @@ class Client { signal: combinedSignal, }); + if (!isValidServerHeader(response)) { + const serverHeader = response.headers.get('Server'); + if (!serverHeader) { + throw new Error('Server must be EventSourcingDB, but Server header is missing.'); + } + throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`); + } + if (response.status !== 200) { throw new Error( `Failed to read events, got HTTP status code '${response.status}', expected '200'.`, @@ -239,6 +260,14 @@ class Client { signal: combinedSignal, }); + if (!isValidServerHeader(response)) { + const serverHeader = response.headers.get('Server'); + if (!serverHeader) { + throw new Error('Server must be EventSourcingDB, but Server header is missing.'); + } + throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`); + } + if (response.status !== 200) { throw new Error( `Failed to run EventQL query, got HTTP status code '${response.status}', expected '200'.`, @@ -314,6 +343,14 @@ class Client { signal: combinedSignal, }); + if (!isValidServerHeader(response)) { + const serverHeader = response.headers.get('Server'); + if (!serverHeader) { + throw new Error('Server must be EventSourcingDB, but Server header is missing.'); + } + throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`); + } + if (response.status !== 200) { throw new Error( `Failed to observe events, got HTTP status code '${response.status}', expected '200'.`, @@ -371,6 +408,10 @@ class Client { }), }); + if (!isValidServerHeader(response)) { + throw new Error('Server must be EventSourcingDB.'); + } + if (response.status !== 200) { throw new Error( `Failed to register event schema, got HTTP status code '${response.status}', expected '200'.`, @@ -411,6 +452,14 @@ class Client { signal: combinedSignal, }); + if (!isValidServerHeader(response)) { + const serverHeader = response.headers.get('Server'); + if (!serverHeader) { + throw new Error('Server must be EventSourcingDB, but Server header is missing.'); + } + throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`); + } + if (response.status !== 200) { throw new Error( `Failed to read subjects, got HTTP status code '${response.status}', expected '200'.`, @@ -460,6 +509,10 @@ class Client { }), }); + if (!isValidServerHeader(response)) { + throw new Error('Server must be EventSourcingDB.'); + } + if (response.status !== 200) { throw new Error( `Failed to read event type, got HTTP status code '${response.status}', expected '200'.`, @@ -504,6 +557,14 @@ class Client { signal: combinedSignal, }); + if (!isValidServerHeader(response)) { + const serverHeader = response.headers.get('Server'); + if (!serverHeader) { + throw new Error('Server must be EventSourcingDB, but Server header is missing.'); + } + throw new Error(`Server must be EventSourcingDB, got Server header: '${serverHeader}'.`); + } + if (response.status !== 200) { throw new Error( `Failed to read event types, got HTTP status code '${response.status}', expected '200'.`, diff --git a/src/isValidServerHeader.ts b/src/isValidServerHeader.ts new file mode 100644 index 0000000..0130d25 --- /dev/null +++ b/src/isValidServerHeader.ts @@ -0,0 +1,15 @@ +const isValidServerHeader = (response: Response): boolean => { + const serverHeader = response.headers.get('Server'); + + if (!serverHeader) { + return false; + } + + if (!serverHeader.startsWith('EventSourcingDB/')) { + return false; + } + + return true; +}; + +export { isValidServerHeader };