dikript-react-identity-comparison-sdk
Version:
A Dikript's React SDK for identity comparison and liveness checks.
222 lines (198 loc) • 7.29 kB
text/typescript
/**
* API utility functions for Dikript Identity Comparison SDK
*/
const LIVENESS_ENDPOINT = '/livelinesscheck';
const IDENTITY_COMPARISON_ENDPOINT = '/identitycomparison';
const DEFAULT_TIMEOUT = 30000; // 30 seconds default timeout
/**
* Helper function to add timeout to fetch requests
* @param {Promise<Response>} fetchPromise - The fetch promise
* @param {number} timeout - Timeout in milliseconds
* @returns {Promise<Response>} - Promise that will reject if timeout is exceeded
*/
function timeoutFetch(fetchPromise: Promise<Response>, timeout: number = DEFAULT_TIMEOUT): Promise<Response> {
let timeoutId: NodeJS.Timeout;
const timeoutPromise = new Promise<Response>((_, reject) => {
timeoutId = setTimeout(() => {
reject(new Error(`Request timed out after ${timeout}ms`));
}, timeout);
});
return Promise.race([
fetchPromise,
timeoutPromise
]).then((response) => {
clearTimeout(timeoutId);
return response;
}).catch((error) => {
clearTimeout(timeoutId);
throw error;
});
}
/**
* Response interface for liveness check
*/
export interface LivenessResponse {
isLive: boolean;
confidence: number;
message?: string;
}
/**
* Response interface for identity comparison
*/
export interface IdentityComparisonResponse {
isMatch: boolean;
confidence: number;
message?: string;
matchDetails?: {
faceMatch?: boolean;
idMatch?: boolean;
};
}
/**
* Send an image for liveness check
* @param {string} dataUrl - Base64 encoded image data URL
* @param {string} apiKey - API key for authentication
* @param {string} apiUrl - Base URL for API requests
* @param {number} timeout - Timeout in milliseconds (optional)
* @returns {Promise<LivenessResponse>} - Response from the liveness check API
*/
export async function sendImageForLiveness(
apiUrl: string,
apiKey: string,
dataUrl: string,
timeout: number = DEFAULT_TIMEOUT
): Promise<LivenessResponse> {
try {
const base64String = dataUrl.split(',')[1];
const formData = new FormData();
formData.append('ImageBase64String', base64String);
console.log('Sending liveness check to:', `${apiUrl}${LIVENESS_ENDPOINT}`);
const fetchPromise = fetch(`${apiUrl}${LIVENESS_ENDPOINT}`, {
method: 'POST',
headers: {
'x-api-key': apiKey,
},
body: formData,
});
const response = await timeoutFetch(fetchPromise, timeout);
if (!response.ok) {
const errorText = await response.text();
console.error('Liveness check failed with status:', response.status, errorText);
throw new Error(`Server error: ${response.status} - ${errorText}`);
}
const result = await response.json();
// Check if the API returned isLively property
if (result.data && typeof result.data.isLively !== 'undefined') {
// Create a properly formatted response
const formattedResponse = {
isLive: result.data.isLively,
confidence: result.data.liveness?.livenessProbability || 0,
message: result.data.isLively ? 'Liveness check passed' : 'Liveness check failed'
};
return formattedResponse;
} else {
return {
isLive: result.isLively || false,
confidence: result.confidence || 0,
message: result.message || ''
};
}
} catch (error) {
console.error('Error in sendImageForLiveness:', error);
throw error;
}
}
/**
* Send an image for identity comparison
* @param {string} dataUrl - Base64 encoded image data URL
* @param {string} idType - Type of ID (e.g., BVN, NIN)
* @param {string} idNumber - ID number
* @param {string} apiKey - API key for authentication
* @param {string} apiUrl - Base URL for API requests
* @param {number} timeout - Timeout in milliseconds (optional)
* @returns {Promise<IdentityComparisonResponse>} - Response from the identity comparison API
*/
export async function sendImageForIdentityComparison(
apiUrl: string,
apiKey: string,
dataUrl: string,
idType: string,
idNumber: string,
timeout: number = DEFAULT_TIMEOUT
): Promise<IdentityComparisonResponse> {
try {
const base64String = dataUrl.split(',')[1];
const formData = new FormData();
formData.append('ImageBase64String', base64String);
formData.append('idType', idType);
formData.append('idNumber', idNumber);
console.log('Sending identity comparison to:', `${apiUrl}${IDENTITY_COMPARISON_ENDPOINT}`);
console.log('ID Type:', idType);
console.log('ID Number:', idNumber);
const fetchPromise = fetch(`${apiUrl}${IDENTITY_COMPARISON_ENDPOINT}`, {
method: 'POST',
headers: {
'x-api-key': apiKey,
},
body: formData,
});
const response = await timeoutFetch(fetchPromise, timeout);
if (!response.ok) {
const errorText = await response.text();
console.error('Identity comparison failed with status:', response.status, errorText);
throw new Error(`Server error: ${response.status} - ${errorText}`);
}
const result = await response.json();
console.log('Identity comparison raw result:', JSON.stringify(result));
// Check if the API returned data in the expected structure
if (result.data && typeof result.data.isMatch !== 'undefined') {
console.log('Found isMatch in result.data:', result.data.isMatch);
// Create a properly formatted response
const formattedResponse = {
isMatch: result.data.isMatch,
confidence: result.data.confidence || 0,
message: result.data.isMatch ? 'Identity matched successfully' : 'Identity did not match',
matchDetails: result.data.detail || {}
};
console.log('Formatted identity comparison response:', formattedResponse);
return formattedResponse;
} else {
console.log('Using fallback response format');
return {
isMatch: result.isMatch || false,
confidence: result.confidence || 0,
message: result.message || ''
};
}
} catch (error) {
console.error('Error in sendImageForIdentityComparison:', error);
throw error;
}
}
/**
* Handle API errors
* @param {unknown} error - Error object
* @throws {Error} - Throws an error with appropriate message
*/
function handleApiError(error: unknown): never {
if (
typeof error === 'object' &&
error !== null &&
'response' in error &&
error.response !== undefined
) {
const responseError = error as { response: { status: number; data?: { message?: string } } };
throw new Error(`Server error: ${responseError.response.status} - ${responseError.response.data?.message || 'Unknown error'}`);
} else if (
typeof error === 'object' &&
error !== null &&
'request' in error &&
error.request !== undefined
) {
throw new Error('Network error. Please check your internet connection and try again.');
} else if (error instanceof Error) {
throw new Error(`Error: ${error.message}`);
} else {
throw new Error('An unknown error occurred');
}
}