import {MsLivenessCreateSessionResponse, SetupInfo, UploadSampleBasicInfo} from "../../core/generated/zenid-types.generated.js"; import {BackendApi, SampleToUpload} from "./backend-api.js"; /// Default implementation of BackendApi for standard ZenID backend. /// /// Customization points (from simplest to most advanced): /// - `modifyHeaders` — add authentication headers, tenant IDs, etc. /// - `modifyRequest` — full request customization (URL rewriting, body wrapping) /// - `get`/`post` — replace the HTTP transport entirely export class ZenidBackendApi implements BackendApi { public readonly baseURL: string; private readonly apiKey?: string; constructor(apiUrl: string, apiKey?: string) { this.baseURL = apiUrl; this.apiKey = apiKey; } // --- Overridable hooks --- /// Override to add custom headers to every outgoing request. /// Default adds API key authorization when initialized with an apiKey. protected modifyHeaders(headers: Headers): void { if (this.apiKey) { headers.set('Authorization', `api_key ${encodeURIComponent(this.apiKey)}`); } } /// Override for full request customization (URL rewriting, body wrapping, etc.). /// Called after modifyHeaders. Return the (possibly modified) request. protected modifyRequest(request: Request): Request { return request; } // --- HTTP methods (overridable) --- protected async get(path: string, queryParams?: string): Promise { const url = queryParams ? `${this.baseURL}/${path}?${queryParams}` : `${this.baseURL}/${path}`; return this.send(url, {method: 'GET'}); } protected async post(path: string, body: BodyInit, contentType: string = 'application/json'): Promise { return this.send(`${this.baseURL}/${path}`, {method: 'POST', headers: {'Content-Type': contentType}, body}); } protected send(url: string, init: RequestInit): Promise { const headers = new Headers(init.headers); this.modifyHeaders(headers); let request = new Request(url, {...init, headers}); request = this.modifyRequest(request); return fetch(request); } // --- BackendApi --- async getSample(sampleId: string): Promise { const response = await this.get(`sample/${sampleId}`); return await response.json() as Promise; } async getSetupInfo(): Promise { const response = await this.get('setupInfo'); return await response.json() as SetupInfo; } async initSdk(token: string): Promise { const response = await this.get('initSdk', `token=${encodeURIComponent(token)}`); const anyJson = await response.json(); return anyJson.Response; } async uploadSample(sampleToUpload: SampleToUpload): Promise { const response = await this.post( `sample${sampleToUpload.getUrlParams()}`, sampleToUpload.file as any, 'application/octet-stream', ); return await response.json() as UploadSampleBasicInfo; } async investigateSamples(sampleIDs: string[], async: boolean = false): Promise { const response = await this.get('investigateSamples', `sampleIDs=${sampleIDs.join("&sampleIDs=")}&async=${async}`); return await response.json(); } getBackendUrl(): string { return this.baseURL; } async msLivenessCreateSession(deviceCorrelationId: string): Promise { const response = await this.post( 'msLiveness/createSession', JSON.stringify({ DeviceCorrelationId: deviceCorrelationId }), ); if (!response.ok) { throw new Error(`msLivenessCreateSession failed: ${response.status} ${response.statusText}`); } const data = await response.json(); if (data.ErrorCode || data.ErrorText) { throw new Error(`msLivenessCreateSession backend error: ${data.ErrorCode ?? ""} ${data.ErrorText ?? ""}`); } return data as MsLivenessCreateSessionResponse; } async msLivenessGetSessionResult(sessionId: string): Promise { const response = await this.get(`msLiveness/sessionResult/${encodeURIComponent(sessionId)}`); if (!response.ok) { throw new Error(`msLivenessGetSessionResult failed: ${response.status} ${response.statusText}`); } const data = await response.json(); if (data.ErrorCode || data.ErrorText) { throw new Error(`msLivenessGetSessionResult backend error: ${data.ErrorCode ?? ""} ${data.ErrorText ?? ""}`); } return JSON.parse(data.ResultJson); } async msLivenessGetSessionImage(sessionImageId: string): Promise { const response = await this.get(`msLiveness/sessionImage/${encodeURIComponent(sessionImageId)}`); if (!response.ok) { throw new Error(`msLivenessGetSessionImage failed: ${response.status} ${response.statusText}`); } const data = await response.json(); if (data.ErrorCode || data.ErrorText) { throw new Error(`msLivenessGetSessionImage backend error: ${data.ErrorCode ?? ""} ${data.ErrorText ?? ""}`); } return data.ImageBase64; } }