@sanctum-key/react-native-sdk 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"KYCService.d.ts","sourceRoot":"","sources":["../../../../src/modules/api/KYCService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KYCService.d.ts","sourceRoot":"","sources":["../../../../src/modules/api/KYCService.ts"],"names":[],"mappings":"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"}
@@ -467,34 +467,38 @@ export class KYCService {
467
467
  throw error;
468
468
  }
469
469
  }
470
- /** Send WhatsApp verification code. POST /api/v1/accounts/send-whatsapp-verification/ */
470
+ /** Send WhatsApp verification code. */
471
471
  async sendWhatsAppVerificationCode(sessionId, phoneNumber, auth) {
472
472
  const url = `${KYCConfig.getBackendUrl()}/accounts/send-whatsapp-verification/`;
473
473
  const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());
474
+ // 🚨 FORMATTING FIX: Strips the "+" sign (e.g., "+254712345" becomes "254712345")
475
+ const formattedPhone = phoneNumber.replace(/[^0-9]/g, '');
474
476
  const res = await axios.post(url, {
475
477
  session_id: sessionId,
476
- phone_number: phoneNumber
478
+ phone_number: formattedPhone
477
479
  }, {
478
480
  headers: {
479
481
  'Content-Type': 'application/json',
482
+ 'Referer': KYCConfig.getBackendUrl(), // CSRF Protection
480
483
  ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),
481
484
  },
482
485
  });
483
486
  return res.data;
484
487
  }
488
+ /** Verify WhatsApp code with OTP. */
485
489
  async verifyWhatsAppCode(sessionId, otp, phoneNumber, auth) {
486
- const url = `${KYCConfig.getBackendUrl()}/accounts/verify-whatsapp-verification/`;
490
+ const url = `${KYCConfig.getBackendUrl()}/accounts/verify-whatsapp-code/`;
487
491
  const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());
492
+ const formattedPhone = phoneNumber.replace(/[^0-9]/g, '');
493
+ const cleanOtp = otp.replace(/[^0-9]/g, '');
488
494
  try {
489
495
  const res = await axios.post(url, {
490
496
  session_id: sessionId,
491
- otp: otp,
492
- phone_number: phoneNumber
497
+ phone_number: formattedPhone,
498
+ verification_code: cleanOtp
493
499
  }, {
494
500
  headers: {
495
501
  'Content-Type': 'application/json',
496
- // 🚨 THE FIX: Spoof the Referer header for Django's CSRF middleware
497
- 'Referer': KYCConfig.getBackendUrl(),
498
502
  ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),
499
503
  },
500
504
  });
@@ -545,8 +549,6 @@ export const authentification = async () => {
545
549
  // 3. Create the request and lock it
546
550
  activeAuthRequest = (async () => {
547
551
  logger.log('Authenticating: Fetching new Keycloak token...');
548
- // 🚨 FIX: Do NOT use URLSearchParams in React Native with Axios.
549
- // Use a raw URL-encoded string to guarantee Keycloak understands the payload.
550
552
  const params = 'client_id=kyc_frontend&client_secret=QhgAmvKgmwODzsEp98dnA4PeUEMMaFHd&grant_type=client_credentials';
551
553
  const res = await axios.post(`https://keycloak.SanctumKey.net/realms/kyc/protocol/openid-connect/token`, params, {
552
554
  headers: {
@@ -567,7 +569,6 @@ export const authentification = async () => {
567
569
  }
568
570
  catch (error) {
569
571
  cachedToken = null; // Clear bad cache
570
- // 🚨 FIX: Extract Keycloak's exact error message so it doesn't log as {}
571
572
  const safeErrorMessage = error?.response?.data?.error_description ||
572
573
  error?.response?.data?.error ||
573
574
  error?.message ||
@@ -1 +1 @@
1
- {"version":3,"file":"KYCService.js","sourceRoot":"","sources":["../../../../src/modules/api/KYCService.ts"],"names":[],"mappings":"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","sourcesContent":["import axios from 'axios';\nimport { GovernmentDocumentType, GovernmentDocumentTypeShorted, OrientationVideoResponse } from '../../types/KYC.types';\nimport { CheckTemplateTypeResponse, ExtractMrzTextResponse } from '../../components/OverLay/type';\nimport { SessionResponse, VerificationResult, VerificationSessionRequest } from './types';\nimport { KycEnvironment } from '../../types/env.types';\nimport { logger } from '../../utils/logger';\nimport { Platform } from 'react-native';\nimport KYCConfig from '../../config/KYCConfig';\n\nconst appendFileToFormData = async (formData: FormData, key: string, uri: string, name: string = 'file.jpg', type: string = 'image/jpeg') => {\n if (Platform.OS === 'web') {\n const response = await fetch(uri);\n const blob = await response.blob();\n formData.append(key, blob, name);\n } else {\n formData.append(key, { uri, type, name } as any);\n }\n};\n\nlet cachedToken: string | null = null;\nlet tokenExpiryTime: number | null = null;\nlet activeAuthRequest: Promise<string> | null = null; \n\nexport interface KYCRequest {\n userId: string;\n documentImage: string;\n selfieImage: string;\n documentType: 'passport' | 'id_card' | 'drivers_license';\n}\n\nexport interface KYCResponse {\n success: boolean;\n verificationId: string;\n status: 'pending' | 'approved' | 'rejected';\n message?: string;\n}\n\nexport interface FaceDetectionRequest {\n selfieImage: string;\n documentImage: string;\n}\n\nexport interface FaceDetectionResponse {\n match: boolean;\n confidence: number;\n message: string;\n}\n\nexport interface SelfieVideoResponse {\n orientation_direction: \"center\" | \"left\" | \"right\",\n turn_score: number;\n bbox: number[];\n capture: boolean;\n instruction: string;\n error: string;\n}\n\n\nexport class KYCService {\n private baseURL: string;\n private apiKey: string;\n // Additional service base URLs (fixed as per current infra)\n private faceServiceURL = 'https://kyc-engine.SanctumKey.net:8000';\n private textExtractionServiceURL = 'https://kyc-engine.SanctumKey.net:8006';\n private mrzServiceURL = 'https://kyc-engine.SanctumKey.net:8002';\n private barcodeServiceURL = 'https://kyc-engine.SanctumKey.net:8000';\n private orientationServiceURL = 'http://18.188.180.154:8080';\n\n constructor(baseURL: string, apiKey: string) {\n this.baseURL = baseURL;\n this.apiKey = apiKey;\n }\n\n private getHeaders() {\n return {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n };\n }\n\n async submitKYC(data: KYCRequest): Promise<KYCResponse> {\n try {\n const response = await axios.post(\n `${this.baseURL}/kyc/submit`,\n data,\n { headers: this.getHeaders() }\n );\n return response.data;\n } catch (error) {\n logger.error('Error submitting KYC:', error);\n throw error;\n }\n }\n\n async detectFace(data: FaceDetectionRequest): Promise<FaceDetectionResponse> {\n try {\n const response = await axios.post(\n `${this.baseURL}/ai/face-detection`,\n data,\n { headers: this.getHeaders() }\n );\n return response.data;\n } catch (error) {\n logger.error('Error detecting face:', error);\n throw error;\n }\n }\n\n async validateDocument(documentImage: string, documentType: string): Promise<any> {\n try {\n const response = await axios.post(\n `${this.baseURL}/ai/document-validation`,\n { documentImage, documentType },\n { headers: this.getHeaders() }\n );\n return response.data;\n } catch (error) {\n logger.error('Error validating document:', error);\n throw error;\n }\n }\n\n async getKYCStatus(verificationId: string): Promise<KYCResponse> {\n try {\n const response = await axios.get(\n `${this.baseURL}/kyc/status/${verificationId}`,\n { headers: this.getHeaders() }\n );\n return response.data;\n } catch (error) {\n logger.error('Error getting KYC status:', error);\n throw error;\n }\n }\n\n async processSelfieOrientationPicture(videoFile: string, token: string): Promise<SelfieVideoResponse[]> {\n \n try {\n const formData = new FormData();\n await appendFileToFormData(formData, 'file', videoFile, 'selfie_picture.jpg', 'image/jpeg');\n\n const response = await axios.post<SelfieVideoResponse[]>(\n `${this.faceServiceURL}/detect_face_orientation/`,\n formData,\n {\n timeout: 20000,\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },\n }\n );\n return response.data;\n } catch (error) {\n logger.error('Error processing selfie orientation:', error);\n throw error;\n }\n }\n\n async processOrientationVideo(videoFile: string, env: KycEnvironment = 'PRODUCTION'): Promise<OrientationVideoResponse> {\n try {\n // SANDBOX mode: skip AI verification and return mock response\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI orientation video processing\");\n logger.log(\"SANDBOX mode: Returning mock orientation video response\");\n return {\n success: true,\n data: {\n center: { captured: true, frame: 10 },\n left: { captured: true, frame: 30 },\n right: { captured: true, frame: 50 }\n },\n message: 'SANDBOX: Orientation video processed successfully (mocked)'\n };\n }\n\n // Create FormData for multipart/form-data request\n const formData = new FormData();\n await appendFileToFormData(formData, 'file', videoFile, 'orientation_video.mp4', 'video/mp4');\n\n\n const response = await axios.post(\n `${this.orientationServiceURL}/process_orientation_video_stream/`,\n formData,\n {\n // Let axios set the proper multipart boundary header automatically\n timeout: 90000,\n }\n );\n\n return {\n success: true,\n data: response.data,\n message: 'Orientation video processed successfully'\n };\n } catch (error: any) {\n logger.error('Error processing orientation video:', JSON.stringify(error, null, 2));\n\n // Handle specific error cases\n if (error.response?.status === 503) {\n return {\n success: false,\n error: {\n code: 'SERVICE_UNAVAILABLE',\n message: 'Service not ready, model not initialized.',\n details: error.response.data\n },\n message: 'Service temporarily unavailable'\n };\n }\n\n return {\n success: false,\n error: {\n code: 'PROCESSING_ERROR',\n message: error.response?.data?.detail || error.message || 'Unknown error occurred',\n details: error.response?.data\n },\n message: 'Failed to process orientation video'\n };\n }\n }\n\n // STEP 1 - ID CARD VALIDATION\n async detectFaceOnId(\n idCardImageUri: string, \n token: string, \n docType: string, \n env: KycEnvironment = 'PRODUCTION'\n ): Promise<{ result: boolean; detail: any[]; card_obb?: any }> { // Added card_obb to signature\n \n // SANDBOX mode\n if (env === 'SANDBOX') {\n logger.log(\"SANDBOX mode: Returning mock face detection response\");\n return {\n result: true,\n detail: [{ confidence: 0.95, bbox: [50, 50, 200, 200] }],\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n \n const formData = new FormData();\n await appendFileToFormData(formData, 'file', idCardImageUri, 'id_card_photo.jpg', 'image/jpeg');\n \n const docTypeShorted = GovernmentDocumentTypeShorted[docType as GovernmentDocumentType];\n \n // Log metadata, NOT the FormData object\n logger.log('detectFaceOnId Request:', { docTypeShorted, imageUri: idCardImageUri });\n \n try {\n const res = await axios.post(\n `${this.faceServiceURL}/detect_face/?doc_type=${docTypeShorted}`, \n formData,\n {\n headers: { \n 'Content-Type': 'multipart/form-data', \n 'Authorization': `Bearer ${token}` \n },\n timeout: 20000 // 20 seconds is good, but ensure the image is compressed before this step!\n }\n );\n \n // It's safe to stringify res.data if the backend returns a clean JSON object\n logger.log('detectFaceOnId res', JSON.stringify(res.data, null, 2));\n \n if (res.data?.result) {\n return res.data;\n }\n \n throw new Error(res.data?.detail || 'detect_face failed');\n \n } catch (error: any) {\n // Use your safe error extractor, avoid JSON.stringify on raw Axios errors\n const safeError = errorMessage(error) || error.message;\n logger.error('Error detecting face on id:', safeError);\n throw error;\n }\n }\n\n //check templatetemplate_type\n async checkTemplateType(params: { fileUri: string; docType: string; docRegion: string; token: string; postfix: string }, env: KycEnvironment = 'PRODUCTION'): Promise<any> {\n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI template type check\");\n logger.log(\"SANDBOX mode: Returning mock template type response\");\n const { docType, docRegion, postfix } = params;\n return {\n template_path: `templates/${docType}_${docRegion}_${postfix}.jpg`,\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n\n const { fileUri, docType, docRegion, token, postfix } = params;\n const formData = new FormData();\n \n // ✅ FIX: Dynamically assign the postfix to the filename\n await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');\n\n const docTypeShorted = GovernmentDocumentTypeShorted[docType as GovernmentDocumentType];\n const url = `${this.mrzServiceURL}/get_template_version/?doc_type=${encodeURIComponent(docTypeShorted)}&doc_region=${encodeURIComponent(docRegion)}&postfix=${postfix}`;\n\n logger.log('checkTemplateType params', this.mrzServiceURL, JSON.stringify({ fileUri, docTypeShorted, docRegion, token, postfix, url }, null, 2));\n try {\n const res = await axios.post<CheckTemplateTypeResponse>(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },\n timeout: 60000,\n });\n logger.log('checkTemplateType res', JSON.stringify(res.data, null, 2));\n return res.data;\n } catch (e: any) {\n logger.error('Error checking template type:', JSON.stringify(e));\n throw e;\n }\n\n }\n\n async extractDocumentInformation(params: { fileUri: string; docType: string; docRegion: string; token: string; postfix?: string }): Promise<any> {\n const { fileUri, docType, docRegion, token, postfix = 'front' } = params;\n const formData = new FormData();\n \n // ✅ FIX: Dynamic filename\n await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');\n\n const url = `${this.textExtractionServiceURL}/extract_doc_information/?doc_type=${encodeURIComponent(docType)}&doc_region=${encodeURIComponent(docRegion)}`;\n const attempt = async () => {\n const res = await axios.post(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },\n timeout: 60000,\n });\n logger.log('extractDocumentInformation res', JSON.stringify(truncateFields(res)));\n\n if (res.data?.detail) throw new Error(res.data.detail);\n return res.data;\n };\n try {\n return await attempt();\n } catch (e) {\n logger.error('Error extracting document information:', JSON.stringify(truncateFields(e)));\n throw e;\n }\n }\n\n // STEP 2 - barcode extraction\n async extractBarcode(params: { fileUri: string; token: string; postfix?: string }, env: KycEnvironment = 'PRODUCTION'): Promise<any> {\n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI barcode extraction\");\n logger.log(\"SANDBOX mode: Returning mock barcode response\");\n return {\n barcode_data: 'SANDBOX_MOCK_BARCODE_DATA',\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n\n const { fileUri, token, postfix = 'back' } = params;\n const formData = new FormData();\n \n // ✅ FIX: Dynamic filename\n await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');\n\n const url = `${this.barcodeServiceURL}/decode_barcode/`;\n const attempt = async () => {\n try {\n const res = await axios.post(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },\n timeout: 60000,\n });\n logger.log('extractBarcode res', JSON.stringify(res.data, null, 2));\n if (Object.keys(res.data).length === 0) throw new Error('No data found');\n return res.data;\n } catch (e: any) {\n throw new Error(e?.message || 'Erreur de détection du barcode');\n }\n };\n try {\n return await attempt();\n } catch (e) {\n logger.error('Error extracting Barcode text:', JSON.stringify(e));\n throw e;\n }\n }\n\n // STEP 3 - MRZ TEXT EXTRACTION\n async extractMrzText(\n params: { \n fileUri: string; \n docType: string; \n docRegion: string; \n postfix?: string; \n token: string; \n template_path: string; \n mrz_type?: string; \n }, \n env: KycEnvironment = 'PRODUCTION'\n ): Promise<any> {\n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI MRZ extraction\");\n logger.log(\"SANDBOX mode: Returning mock MRZ response\");\n const { docType, docRegion, postfix = 'back', mrz_type } = params;\n return {\n success: true,\n parsed_data: {\n status: 'success',\n document_type: docType,\n mrz_type: mrz_type || 'TD1',\n doc_region: docRegion,\n postfix: postfix\n },\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n\n const { fileUri, docType, docRegion, postfix = 'back', token, template_path, mrz_type } = params;\n const formData = new FormData();\n \n // ✅ Dynamic filename to prevent passports from crashing (since their MRZ is on the front)\n await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');\n\n const docTypeShorted = GovernmentDocumentTypeShorted[docType as GovernmentDocumentType] || docType;\n logger.log(\"docTypeShorted\", docTypeShorted, docRegion, postfix);\n\n let url = `${this.mrzServiceURL}/extract_mrz_text/?doc_type=${encodeURIComponent(docTypeShorted)}&doc_region=${encodeURIComponent(docRegion)}&postfix=${encodeURIComponent(postfix)}&template_path=${encodeURIComponent(template_path)}`;\n \n if (mrz_type && mrz_type.trim() !== '') {\n url += `&mrz_type=${encodeURIComponent(mrz_type)}`;\n }\n \n logger.log(\"url\", url);\n\n const attempt = async () => {\n try {\n const res = await axios.post<ExtractMrzTextResponse>(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}` },\n // Note: Reduced timeout to 10000ms (10s) based on our earlier network fix to prevent infinite hanging!\n timeout: 10000, \n });\n \n logger.log('extractMrzText res', JSON.stringify(res.data, null, 2));\n \n if (Object.keys(res.data).length === 0) throw new Error('No data found');\n if (res.data?.success === false) throw new Error(res.data.parsed_data?.status || 'Échec de l\\'extraction MRZ');\n \n return res.data;\n } catch (e: any) {\n throw new Error(e?.message || 'Erreur de détection du MRZ');\n }\n };\n\n try {\n return await attempt();\n } catch (e) {\n logger.error('Error extracting MRZ text:', JSON.stringify(errorMessage(e), null, 2));\n throw e;\n }\n }\n\n // STEP 2 - SELFIE VALIDATION\n async recognizeFace(params: { idPhotoUri: string; selfiePhotoUri: string }, env: KycEnvironment = 'PRODUCTION'): Promise<{ is_match: boolean; similarity: number; id_bbox?: number[]; selfie_bbox?: number[] }> {\n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI face recognition\");\n logger.log(\"SANDBOX mode: Returning mock face recognition response\");\n return {\n is_match: true,\n similarity: 0.95,\n id_bbox: [50, 50, 200, 200],\n selfie_bbox: [50, 50, 200, 200]\n };\n }\n\n const { idPhotoUri, selfiePhotoUri } = params;\n const formData = new FormData();\n await appendFileToFormData(formData, 'id_photo', idPhotoUri, 'id_card_photo.jpg', 'image/jpeg');\n await appendFileToFormData(formData, 'selfie_photo', selfiePhotoUri, 'selfie_final.jpg', 'image/jpeg');\n\n const res = await axios.post(`${this.faceServiceURL}/recognize_face/`, formData, { timeout: 45000 });\n if (res.data?.detail) throw new Error(res.data.detail);\n return res.data;\n }\n\n // HEALTH CHECKS\n async healthFaceDetection(): Promise<any> {\n const res = await axios.get(`${this.faceServiceURL}/health`);\n return res.data;\n }\n\n async healthTextExtraction(): Promise<any> {\n const res = await axios.get(`${this.textExtractionServiceURL}/health`);\n return res.data;\n }\n\n async healthMrzService(): Promise<any> {\n const res = await axios.get(`${this.mrzServiceURL}/health`);\n return res.data;\n }\n\n async healthOrientationService(): Promise<any> {\n const res = await axios.get(`${this.orientationServiceURL}/health`);\n return res.data;\n }\n\n async newSession({ token, apiKey }: { token?: string, apiKey?: string }): Promise<SessionResponse> {\n try {\n const data = {\n \"status\": \"PENDING\",\n \"metadata\": {},\n }\n const res = await axios.post<SessionResponse>(`${KYCConfig.getBackendUrl()}/verification/sessions/`,\n data, {\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { 'Authorization': `ApiKey ${apiKey}` } : { 'Authorization': `Bearer ${token}` })\n }\n });\n return res.data;\n } catch (error: any) {\n logger.error('Error creating session:', JSON.stringify(errorMessage(error), null, 2));\n\n // Extract backend error message if available\n const backendMessage = errorMessage(error);\n\n if (backendMessage) {\n logger.error('Backend error message:', JSON.stringify(truncateFields(backendMessage), null, 2));\n throw new Error(`Backend error: ${JSON.stringify(truncateFields(backendMessage))}`);\n }\n\n throw error;\n }\n }\n\n async verificationSession(payload: VerificationSessionRequest): Promise<any> {\n console.log('apiKey in verificationSession', payload.apiKey);\n try {\n const { session_id, step, data, templateId, action, apiKey } = payload;\n const token = apiKey ? undefined : await authentification();\n const payloadData = {\n action: action,\n data: {\n step,\n templateId,\n ...(action === \"location_permission\" ? { permissionGranted: true, } : {}),\n ...data,\n },\n ...({ session_id: session_id }),\n timestamp: new Date().toISOString()\n }\n const url = `${KYCConfig.getBackendUrl()}/verification/api/kyc/sessions/${session_id}/steps/${step}/`;\n\n const logPayload = truncateFields({ payloadData, session_id, step });\n logger.log('verificationSession payload',\n JSON.stringify(truncateFields({ logPayload, token: token ?? \"-\", path: url, apiKey }),\n null, 2))\n\n const res = await axios.post<SessionResponse>(url,\n payloadData,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { 'Authorization': `ApiKey ${apiKey}` } : { 'Authorization': `Bearer ${token}` })\n }\n });\n logger.log('verificationSession res', JSON.stringify(truncateFields(res.data), null, 2));\n return res.data;\n\n } catch (error) {\n logger.error('Error validating component:', JSON.stringify(error, null, 2));\n throw new Error(errorMessage(error));\n }\n }\n\n /** Send email verification code. POST /api/v1/accounts/email/send/ */\n async sendEmailVerificationCode(\n email: string,\n auth?: { apiKey?: string; token?: string }\n ): Promise<unknown> {\n const url = `${KYCConfig.getBackendUrl()}/accounts/email/send/`;\n const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());\n const res = await axios.post(\n url,\n { email },\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),\n },\n }\n );\n return res.data;\n }\n\n /** Verify email with OTP. POST /api/v1/accounts/email/verify/ */\n async verifyEmailCode(\n otp: string,\n auth?: { apiKey?: string; token?: string }\n ): Promise<unknown> {\n const url = `${KYCConfig.getBackendUrl()}/accounts/email/verify/`;\n const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());\n const res = await axios.post(\n url,\n { otp },\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),\n },\n }\n );\n return res.data;\n }\n\n async getVerificationResult(session_id: string): Promise<VerificationResult> {\n try {\n const token = await authentification();\n const url = `${KYCConfig.getBackendUrl()}/verification/api/kyc/result/?session_id=${session_id}`;\n const res = await axios.get<VerificationResult>(url,\n { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } });\n logger.log('getVerificationResult res', JSON.stringify(truncateFields(res.data), null, 2));\n return res.data;\n } catch (error) {\n logger.error('Error getting verification result:', JSON.stringify(errorMessage(error), null, 2));\n throw error;\n }\n }\n\n /** Send WhatsApp verification code. POST /api/v1/accounts/send-whatsapp-verification/ */\n async sendWhatsAppVerificationCode(\n sessionId: string,\n phoneNumber: string,\n auth?: { apiKey?: string; token?: string }\n ): Promise<unknown> {\n const url = `${KYCConfig.getBackendUrl()}/accounts/send-whatsapp-verification/`;\n const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());\n \n const res = await axios.post(\n url,\n {\n session_id: sessionId,\n phone_number: phoneNumber\n },\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),\n },\n }\n );\n return res.data;\n }\n\n async verifyWhatsAppCode(\n sessionId: string,\n otp: string,\n phoneNumber: string, \n auth?: { apiKey?: string; token?: string }\n ): Promise<unknown> {\n \n const url = `${KYCConfig.getBackendUrl()}/accounts/verify-whatsapp-verification/`; \n const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());\n \n try {\n const res = await axios.post(\n url,\n { \n session_id: sessionId,\n otp: otp,\n phone_number: phoneNumber \n },\n {\n headers: {\n 'Content-Type': 'application/json',\n \n // 🚨 THE FIX: Spoof the Referer header for Django's CSRF middleware\n 'Referer': KYCConfig.getBackendUrl(), \n \n ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),\n },\n }\n );\n return res.data;\n } catch (error: any) {\n console.error(\"WhatsApp Verify API Error: \", error.response?.data || error.message);\n throw error;\n }\n }\n}\n\nconst kycService = new KYCService(\"\", \"\");\nexport default kycService;\n\n// Pour éviter d'afficher des champs trop longs, on tronque les valeurs longues dans le log\nexport function truncateFields(obj: any, maxLength = 420): any {\n if (typeof obj !== 'object' || obj === null) return obj;\n if (Array.isArray(obj)) return obj.map(item => truncateFields(item, maxLength));\n const truncated: any = {};\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n const value = obj[key];\n if (typeof value === 'string' && value.length > maxLength) {\n truncated[key] = value.slice(0, maxLength) + '... [truncated]';\n } else if (typeof value === 'object' && value !== null) {\n truncated[key] = truncateFields(value, maxLength);\n } else {\n truncated[key] = value;\n }\n }\n return truncated;\n}\n\n\n\n\n// Strictly define the return type as Promise<string>\nexport const authentification = async (): Promise<string> => {\n try {\n // 1. If we have a valid token (with 10 seconds of breathing room), return it immediately\n if (cachedToken && tokenExpiryTime && Date.now() < tokenExpiryTime - 10000) {\n return cachedToken;\n }\n\n // 2. RACE CONDITION PREVENTION\n if (activeAuthRequest) {\n return activeAuthRequest;\n }\n\n // 3. Create the request and lock it\n activeAuthRequest = (async () => {\n logger.log('Authenticating: Fetching new Keycloak token...');\n \n // 🚨 FIX: Do NOT use URLSearchParams in React Native with Axios.\n // Use a raw URL-encoded string to guarantee Keycloak understands the payload.\n const params = 'client_id=kyc_frontend&client_secret=QhgAmvKgmwODzsEp98dnA4PeUEMMaFHd&grant_type=client_credentials';\n \n const res = await axios.post(\n `https://keycloak.SanctumKey.net/realms/kyc/protocol/openid-connect/token`,\n params,\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n }\n );\n \n cachedToken = res.data.access_token;\n \n if (!cachedToken) {\n throw new Error(\"Keycloak returned a success response but no access_token was found.\");\n }\n\n // Calculate exact expiry timestamp (expires_in is usually in seconds)\n const expiresInMs = (res.data.expires_in || 300) * 1000; \n tokenExpiryTime = Date.now() + expiresInMs;\n\n return cachedToken; \n })();\n\n const finalToken = await activeAuthRequest;\n return finalToken;\n\n } catch (error: any) {\n cachedToken = null; // Clear bad cache\n \n // 🚨 FIX: Extract Keycloak's exact error message so it doesn't log as {}\n const safeErrorMessage = \n error?.response?.data?.error_description || \n error?.response?.data?.error || \n error?.message || \n 'Unknown network error';\n \n logger.error('Error authentifying:', safeErrorMessage);\n throw new Error(`Échec de l'authentification: ${safeErrorMessage}`);\n \n } finally {\n // 4. Always clear the lock when the request finishes\n activeAuthRequest = null;\n }\n}\n\nexport const errorMessage = (error: any) => {\n return error.response?.data?.message ||\n error.response?.data?.detail ||\n error.response?.data?.error ||\n error.response?.data;\n}"]}
1
+ {"version":3,"file":"KYCService.js","sourceRoot":"","sources":["../../../../src/modules/api/KYCService.ts"],"names":[],"mappings":"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","sourcesContent":["import axios from 'axios';\nimport { GovernmentDocumentType, GovernmentDocumentTypeShorted, OrientationVideoResponse } from '../../types/KYC.types';\nimport { CheckTemplateTypeResponse, ExtractMrzTextResponse } from '../../components/OverLay/type';\nimport { SessionResponse, VerificationResult, VerificationSessionRequest } from './types';\nimport { KycEnvironment } from '../../types/env.types';\nimport { logger } from '../../utils/logger';\nimport { Platform } from 'react-native';\nimport KYCConfig from '../../config/KYCConfig';\n\nconst appendFileToFormData = async (formData: FormData, key: string, uri: string, name: string = 'file.jpg', type: string = 'image/jpeg') => {\n if (Platform.OS === 'web') {\n const response = await fetch(uri);\n const blob = await response.blob();\n formData.append(key, blob, name);\n } else {\n formData.append(key, { uri, type, name } as any);\n }\n};\n\nlet cachedToken: string | null = null;\nlet tokenExpiryTime: number | null = null;\nlet activeAuthRequest: Promise<string> | null = null; \n\nexport interface KYCRequest {\n userId: string;\n documentImage: string;\n selfieImage: string;\n documentType: 'passport' | 'id_card' | 'drivers_license';\n}\n\nexport interface KYCResponse {\n success: boolean;\n verificationId: string;\n status: 'pending' | 'approved' | 'rejected';\n message?: string;\n}\n\nexport interface FaceDetectionRequest {\n selfieImage: string;\n documentImage: string;\n}\n\nexport interface FaceDetectionResponse {\n match: boolean;\n confidence: number;\n message: string;\n}\n\nexport interface SelfieVideoResponse {\n orientation_direction: \"center\" | \"left\" | \"right\",\n turn_score: number;\n bbox: number[];\n capture: boolean;\n instruction: string;\n error: string;\n}\n\n\nexport class KYCService {\n private baseURL: string;\n private apiKey: string;\n // Additional service base URLs (fixed as per current infra)\n private faceServiceURL = 'https://kyc-engine.SanctumKey.net:8000';\n private textExtractionServiceURL = 'https://kyc-engine.SanctumKey.net:8006';\n private mrzServiceURL = 'https://kyc-engine.SanctumKey.net:8002';\n private barcodeServiceURL = 'https://kyc-engine.SanctumKey.net:8000';\n private orientationServiceURL = 'http://18.188.180.154:8080';\n\n constructor(baseURL: string, apiKey: string) {\n this.baseURL = baseURL;\n this.apiKey = apiKey;\n }\n\n private getHeaders() {\n return {\n 'Authorization': `Bearer ${this.apiKey}`,\n 'Content-Type': 'application/json',\n };\n }\n\n async submitKYC(data: KYCRequest): Promise<KYCResponse> {\n try {\n const response = await axios.post(\n `${this.baseURL}/kyc/submit`,\n data,\n { headers: this.getHeaders() }\n );\n return response.data;\n } catch (error) {\n logger.error('Error submitting KYC:', error);\n throw error;\n }\n }\n\n async detectFace(data: FaceDetectionRequest): Promise<FaceDetectionResponse> {\n try {\n const response = await axios.post(\n `${this.baseURL}/ai/face-detection`,\n data,\n { headers: this.getHeaders() }\n );\n return response.data;\n } catch (error) {\n logger.error('Error detecting face:', error);\n throw error;\n }\n }\n\n async validateDocument(documentImage: string, documentType: string): Promise<any> {\n try {\n const response = await axios.post(\n `${this.baseURL}/ai/document-validation`,\n { documentImage, documentType },\n { headers: this.getHeaders() }\n );\n return response.data;\n } catch (error) {\n logger.error('Error validating document:', error);\n throw error;\n }\n }\n\n async getKYCStatus(verificationId: string): Promise<KYCResponse> {\n try {\n const response = await axios.get(\n `${this.baseURL}/kyc/status/${verificationId}`,\n { headers: this.getHeaders() }\n );\n return response.data;\n } catch (error) {\n logger.error('Error getting KYC status:', error);\n throw error;\n }\n }\n\n async processSelfieOrientationPicture(videoFile: string, token: string): Promise<SelfieVideoResponse[]> {\n \n try {\n const formData = new FormData();\n await appendFileToFormData(formData, 'file', videoFile, 'selfie_picture.jpg', 'image/jpeg');\n\n const response = await axios.post<SelfieVideoResponse[]>(\n `${this.faceServiceURL}/detect_face_orientation/`,\n formData,\n {\n timeout: 20000,\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },\n }\n );\n return response.data;\n } catch (error) {\n logger.error('Error processing selfie orientation:', error);\n throw error;\n }\n }\n\n async processOrientationVideo(videoFile: string, env: KycEnvironment = 'PRODUCTION'): Promise<OrientationVideoResponse> {\n try {\n // SANDBOX mode: skip AI verification and return mock response\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI orientation video processing\");\n logger.log(\"SANDBOX mode: Returning mock orientation video response\");\n return {\n success: true,\n data: {\n center: { captured: true, frame: 10 },\n left: { captured: true, frame: 30 },\n right: { captured: true, frame: 50 }\n },\n message: 'SANDBOX: Orientation video processed successfully (mocked)'\n };\n }\n\n // Create FormData for multipart/form-data request\n const formData = new FormData();\n await appendFileToFormData(formData, 'file', videoFile, 'orientation_video.mp4', 'video/mp4');\n\n\n const response = await axios.post(\n `${this.orientationServiceURL}/process_orientation_video_stream/`,\n formData,\n {\n // Let axios set the proper multipart boundary header automatically\n timeout: 90000,\n }\n );\n\n return {\n success: true,\n data: response.data,\n message: 'Orientation video processed successfully'\n };\n } catch (error: any) {\n logger.error('Error processing orientation video:', JSON.stringify(error, null, 2));\n\n // Handle specific error cases\n if (error.response?.status === 503) {\n return {\n success: false,\n error: {\n code: 'SERVICE_UNAVAILABLE',\n message: 'Service not ready, model not initialized.',\n details: error.response.data\n },\n message: 'Service temporarily unavailable'\n };\n }\n\n return {\n success: false,\n error: {\n code: 'PROCESSING_ERROR',\n message: error.response?.data?.detail || error.message || 'Unknown error occurred',\n details: error.response?.data\n },\n message: 'Failed to process orientation video'\n };\n }\n }\n\n // STEP 1 - ID CARD VALIDATION\n async detectFaceOnId(\n idCardImageUri: string, \n token: string, \n docType: string, \n env: KycEnvironment = 'PRODUCTION'\n ): Promise<{ result: boolean; detail: any[]; card_obb?: any }> { // Added card_obb to signature\n \n // SANDBOX mode\n if (env === 'SANDBOX') {\n logger.log(\"SANDBOX mode: Returning mock face detection response\");\n return {\n result: true,\n detail: [{ confidence: 0.95, bbox: [50, 50, 200, 200] }],\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n \n const formData = new FormData();\n await appendFileToFormData(formData, 'file', idCardImageUri, 'id_card_photo.jpg', 'image/jpeg');\n \n const docTypeShorted = GovernmentDocumentTypeShorted[docType as GovernmentDocumentType];\n \n // Log metadata, NOT the FormData object\n logger.log('detectFaceOnId Request:', { docTypeShorted, imageUri: idCardImageUri });\n \n try {\n const res = await axios.post(\n `${this.faceServiceURL}/detect_face/?doc_type=${docTypeShorted}`, \n formData,\n {\n headers: { \n 'Content-Type': 'multipart/form-data', \n 'Authorization': `Bearer ${token}` \n },\n timeout: 20000 // 20 seconds is good, but ensure the image is compressed before this step!\n }\n );\n \n // It's safe to stringify res.data if the backend returns a clean JSON object\n logger.log('detectFaceOnId res', JSON.stringify(res.data, null, 2));\n \n if (res.data?.result) {\n return res.data;\n }\n \n throw new Error(res.data?.detail || 'detect_face failed');\n \n } catch (error: any) {\n // Use your safe error extractor, avoid JSON.stringify on raw Axios errors\n const safeError = errorMessage(error) || error.message;\n logger.error('Error detecting face on id:', safeError);\n throw error;\n }\n }\n\n //check templatetemplate_type\n async checkTemplateType(params: { fileUri: string; docType: string; docRegion: string; token: string; postfix: string }, env: KycEnvironment = 'PRODUCTION'): Promise<any> {\n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI template type check\");\n logger.log(\"SANDBOX mode: Returning mock template type response\");\n const { docType, docRegion, postfix } = params;\n return {\n template_path: `templates/${docType}_${docRegion}_${postfix}.jpg`,\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n\n const { fileUri, docType, docRegion, token, postfix } = params;\n const formData = new FormData();\n \n // ✅ FIX: Dynamically assign the postfix to the filename\n await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');\n\n const docTypeShorted = GovernmentDocumentTypeShorted[docType as GovernmentDocumentType];\n const url = `${this.mrzServiceURL}/get_template_version/?doc_type=${encodeURIComponent(docTypeShorted)}&doc_region=${encodeURIComponent(docRegion)}&postfix=${postfix}`;\n\n logger.log('checkTemplateType params', this.mrzServiceURL, JSON.stringify({ fileUri, docTypeShorted, docRegion, token, postfix, url }, null, 2));\n try {\n const res = await axios.post<CheckTemplateTypeResponse>(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },\n timeout: 60000,\n });\n logger.log('checkTemplateType res', JSON.stringify(res.data, null, 2));\n return res.data;\n } catch (e: any) {\n logger.error('Error checking template type:', JSON.stringify(e));\n throw e;\n }\n\n }\n\n async extractDocumentInformation(params: { fileUri: string; docType: string; docRegion: string; token: string; postfix?: string }): Promise<any> {\n const { fileUri, docType, docRegion, token, postfix = 'front' } = params;\n const formData = new FormData();\n \n // ✅ FIX: Dynamic filename\n await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');\n\n const url = `${this.textExtractionServiceURL}/extract_doc_information/?doc_type=${encodeURIComponent(docType)}&doc_region=${encodeURIComponent(docRegion)}`;\n const attempt = async () => {\n const res = await axios.post(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },\n timeout: 60000,\n });\n logger.log('extractDocumentInformation res', JSON.stringify(truncateFields(res)));\n\n if (res.data?.detail) throw new Error(res.data.detail);\n return res.data;\n };\n try {\n return await attempt();\n } catch (e) {\n logger.error('Error extracting document information:', JSON.stringify(truncateFields(e)));\n throw e;\n }\n }\n\n // STEP 2 - barcode extraction\n async extractBarcode(params: { fileUri: string; token: string; postfix?: string }, env: KycEnvironment = 'PRODUCTION'): Promise<any> {\n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI barcode extraction\");\n logger.log(\"SANDBOX mode: Returning mock barcode response\");\n return {\n barcode_data: 'SANDBOX_MOCK_BARCODE_DATA',\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n\n const { fileUri, token, postfix = 'back' } = params;\n const formData = new FormData();\n \n // ✅ FIX: Dynamic filename\n await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');\n\n const url = `${this.barcodeServiceURL}/decode_barcode/`;\n const attempt = async () => {\n try {\n const res = await axios.post(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}`, },\n timeout: 60000,\n });\n logger.log('extractBarcode res', JSON.stringify(res.data, null, 2));\n if (Object.keys(res.data).length === 0) throw new Error('No data found');\n return res.data;\n } catch (e: any) {\n throw new Error(e?.message || 'Erreur de détection du barcode');\n }\n };\n try {\n return await attempt();\n } catch (e) {\n logger.error('Error extracting Barcode text:', JSON.stringify(e));\n throw e;\n }\n }\n\n // STEP 3 - MRZ TEXT EXTRACTION\n async extractMrzText(\n params: { \n fileUri: string; \n docType: string; \n docRegion: string; \n postfix?: string; \n token: string; \n template_path: string; \n mrz_type?: string; \n }, \n env: KycEnvironment = 'PRODUCTION'\n ): Promise<any> {\n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI MRZ extraction\");\n logger.log(\"SANDBOX mode: Returning mock MRZ response\");\n const { docType, docRegion, postfix = 'back', mrz_type } = params;\n return {\n success: true,\n parsed_data: {\n status: 'success',\n document_type: docType,\n mrz_type: mrz_type || 'TD1',\n doc_region: docRegion,\n postfix: postfix\n },\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n\n const { fileUri, docType, docRegion, postfix = 'back', token, template_path, mrz_type } = params;\n const formData = new FormData();\n \n // ✅ Dynamic filename to prevent passports from crashing (since their MRZ is on the front)\n await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');\n\n const docTypeShorted = GovernmentDocumentTypeShorted[docType as GovernmentDocumentType] || docType;\n logger.log(\"docTypeShorted\", docTypeShorted, docRegion, postfix);\n\n let url = `${this.mrzServiceURL}/extract_mrz_text/?doc_type=${encodeURIComponent(docTypeShorted)}&doc_region=${encodeURIComponent(docRegion)}&postfix=${encodeURIComponent(postfix)}&template_path=${encodeURIComponent(template_path)}`;\n \n if (mrz_type && mrz_type.trim() !== '') {\n url += `&mrz_type=${encodeURIComponent(mrz_type)}`;\n }\n \n logger.log(\"url\", url);\n\n const attempt = async () => {\n try {\n const res = await axios.post<ExtractMrzTextResponse>(url, formData, {\n headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}` },\n // Note: Reduced timeout to 10000ms (10s) based on our earlier network fix to prevent infinite hanging!\n timeout: 10000, \n });\n \n logger.log('extractMrzText res', JSON.stringify(res.data, null, 2));\n \n if (Object.keys(res.data).length === 0) throw new Error('No data found');\n if (res.data?.success === false) throw new Error(res.data.parsed_data?.status || 'Échec de l\\'extraction MRZ');\n \n return res.data;\n } catch (e: any) {\n throw new Error(e?.message || 'Erreur de détection du MRZ');\n }\n };\n\n try {\n return await attempt();\n } catch (e) {\n logger.error('Error extracting MRZ text:', JSON.stringify(errorMessage(e), null, 2));\n throw e;\n }\n }\n\n // STEP 2 - SELFIE VALIDATION\n async recognizeFace(params: { idPhotoUri: string; selfiePhotoUri: string }, env: KycEnvironment = 'PRODUCTION'): Promise<{ is_match: boolean; similarity: number; id_bbox?: number[]; selfie_bbox?: number[] }> {\n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI face recognition\");\n logger.log(\"SANDBOX mode: Returning mock face recognition response\");\n return {\n is_match: true,\n similarity: 0.95,\n id_bbox: [50, 50, 200, 200],\n selfie_bbox: [50, 50, 200, 200]\n };\n }\n\n const { idPhotoUri, selfiePhotoUri } = params;\n const formData = new FormData();\n await appendFileToFormData(formData, 'id_photo', idPhotoUri, 'id_card_photo.jpg', 'image/jpeg');\n await appendFileToFormData(formData, 'selfie_photo', selfiePhotoUri, 'selfie_final.jpg', 'image/jpeg');\n\n const res = await axios.post(`${this.faceServiceURL}/recognize_face/`, formData, { timeout: 45000 });\n if (res.data?.detail) throw new Error(res.data.detail);\n return res.data;\n }\n\n // HEALTH CHECKS\n async healthFaceDetection(): Promise<any> {\n const res = await axios.get(`${this.faceServiceURL}/health`);\n return res.data;\n }\n\n async healthTextExtraction(): Promise<any> {\n const res = await axios.get(`${this.textExtractionServiceURL}/health`);\n return res.data;\n }\n\n async healthMrzService(): Promise<any> {\n const res = await axios.get(`${this.mrzServiceURL}/health`);\n return res.data;\n }\n\n async healthOrientationService(): Promise<any> {\n const res = await axios.get(`${this.orientationServiceURL}/health`);\n return res.data;\n }\n\n async newSession({ token, apiKey }: { token?: string, apiKey?: string }): Promise<SessionResponse> {\n try {\n const data = {\n \"status\": \"PENDING\",\n \"metadata\": {},\n }\n const res = await axios.post<SessionResponse>(`${KYCConfig.getBackendUrl()}/verification/sessions/`,\n data, {\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { 'Authorization': `ApiKey ${apiKey}` } : { 'Authorization': `Bearer ${token}` })\n }\n });\n return res.data;\n } catch (error: any) {\n logger.error('Error creating session:', JSON.stringify(errorMessage(error), null, 2));\n\n // Extract backend error message if available\n const backendMessage = errorMessage(error);\n\n if (backendMessage) {\n logger.error('Backend error message:', JSON.stringify(truncateFields(backendMessage), null, 2));\n throw new Error(`Backend error: ${JSON.stringify(truncateFields(backendMessage))}`);\n }\n\n throw error;\n }\n }\n\n async verificationSession(payload: VerificationSessionRequest): Promise<any> {\n console.log('apiKey in verificationSession', payload.apiKey);\n try {\n const { session_id, step, data, templateId, action, apiKey } = payload;\n const token = apiKey ? undefined : await authentification();\n const payloadData = {\n action: action,\n data: {\n step,\n templateId,\n ...(action === \"location_permission\" ? { permissionGranted: true, } : {}),\n ...data,\n },\n ...({ session_id: session_id }),\n timestamp: new Date().toISOString()\n }\n const url = `${KYCConfig.getBackendUrl()}/verification/api/kyc/sessions/${session_id}/steps/${step}/`;\n\n const logPayload = truncateFields({ payloadData, session_id, step });\n logger.log('verificationSession payload',\n JSON.stringify(truncateFields({ logPayload, token: token ?? \"-\", path: url, apiKey }),\n null, 2))\n\n const res = await axios.post<SessionResponse>(url,\n payloadData,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { 'Authorization': `ApiKey ${apiKey}` } : { 'Authorization': `Bearer ${token}` })\n }\n });\n logger.log('verificationSession res', JSON.stringify(truncateFields(res.data), null, 2));\n return res.data;\n\n } catch (error) {\n logger.error('Error validating component:', JSON.stringify(error, null, 2));\n throw new Error(errorMessage(error));\n }\n }\n\n /** Send email verification code. POST /api/v1/accounts/email/send/ */\n async sendEmailVerificationCode(\n email: string,\n auth?: { apiKey?: string; token?: string }\n ): Promise<unknown> {\n const url = `${KYCConfig.getBackendUrl()}/accounts/email/send/`;\n const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());\n const res = await axios.post(\n url,\n { email },\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),\n },\n }\n );\n return res.data;\n }\n\n /** Verify email with OTP. POST /api/v1/accounts/email/verify/ */\n async verifyEmailCode(\n otp: string,\n auth?: { apiKey?: string; token?: string }\n ): Promise<unknown> {\n const url = `${KYCConfig.getBackendUrl()}/accounts/email/verify/`;\n const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());\n const res = await axios.post(\n url,\n { otp },\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),\n },\n }\n );\n return res.data;\n }\n\n async getVerificationResult(session_id: string): Promise<VerificationResult> {\n try {\n const token = await authentification();\n const url = `${KYCConfig.getBackendUrl()}/verification/api/kyc/result/?session_id=${session_id}`;\n const res = await axios.get<VerificationResult>(url,\n { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } });\n logger.log('getVerificationResult res', JSON.stringify(truncateFields(res.data), null, 2));\n return res.data;\n } catch (error) {\n logger.error('Error getting verification result:', JSON.stringify(errorMessage(error), null, 2));\n throw error;\n }\n }\n\n /** Send WhatsApp verification code. */\n async sendWhatsAppVerificationCode(\n sessionId: string,\n phoneNumber: string,\n auth?: { apiKey?: string; token?: string }\n ): Promise<unknown> {\n const url = `${KYCConfig.getBackendUrl()}/accounts/send-whatsapp-verification/`;\n const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());\n \n // 🚨 FORMATTING FIX: Strips the \"+\" sign (e.g., \"+254712345\" becomes \"254712345\")\n const formattedPhone = phoneNumber.replace(/[^0-9]/g, '');\n\n const res = await axios.post(\n url,\n {\n session_id: sessionId,\n phone_number: formattedPhone \n },\n {\n headers: {\n 'Content-Type': 'application/json',\n 'Referer': KYCConfig.getBackendUrl(), // CSRF Protection\n ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),\n },\n }\n );\n return res.data;\n }\n\n /** Verify WhatsApp code with OTP. */\n async verifyWhatsAppCode(\n sessionId: string,\n otp: string,\n phoneNumber: string, \n auth?: { apiKey?: string; token?: string }\n ): Promise<unknown> {\n const url = `${KYCConfig.getBackendUrl()}/accounts/verify-whatsapp-code/`; \n const token = auth?.apiKey ? undefined : (auth?.token ?? await authentification());\n \n const formattedPhone = phoneNumber.replace(/[^0-9]/g, '');\n const cleanOtp = otp.replace(/[^0-9]/g, '');\n\n try {\n const res = await axios.post(\n url,\n { \n session_id: sessionId,\n phone_number: formattedPhone,\n verification_code: cleanOtp \n },\n {\n headers: {\n 'Content-Type': 'application/json', \n ...(auth?.apiKey ? { 'Authorization': `ApiKey ${auth.apiKey}` } : { 'Authorization': `Bearer ${token}` }),\n },\n }\n );\n return res.data;\n } catch (error: any) {\n console.error(\"WhatsApp Verify API Error: \", error.response?.data || error.message);\n throw error;\n }\n }\n}\n\nconst kycService = new KYCService(\"\", \"\");\nexport default kycService;\n\n// Pour éviter d'afficher des champs trop longs, on tronque les valeurs longues dans le log\nexport function truncateFields(obj: any, maxLength = 420): any {\n if (typeof obj !== 'object' || obj === null) return obj;\n if (Array.isArray(obj)) return obj.map(item => truncateFields(item, maxLength));\n const truncated: any = {};\n for (const key in obj) {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;\n const value = obj[key];\n if (typeof value === 'string' && value.length > maxLength) {\n truncated[key] = value.slice(0, maxLength) + '... [truncated]';\n } else if (typeof value === 'object' && value !== null) {\n truncated[key] = truncateFields(value, maxLength);\n } else {\n truncated[key] = value;\n }\n }\n return truncated;\n}\n\n\n\n\n// Strictly define the return type as Promise<string>\nexport const authentification = async (): Promise<string> => {\n try {\n // 1. If we have a valid token (with 10 seconds of breathing room), return it immediately\n if (cachedToken && tokenExpiryTime && Date.now() < tokenExpiryTime - 10000) {\n return cachedToken;\n }\n\n // 2. RACE CONDITION PREVENTION\n if (activeAuthRequest) {\n return activeAuthRequest;\n }\n\n // 3. Create the request and lock it\n activeAuthRequest = (async () => {\n logger.log('Authenticating: Fetching new Keycloak token...');\n \n \n const params = 'client_id=kyc_frontend&client_secret=QhgAmvKgmwODzsEp98dnA4PeUEMMaFHd&grant_type=client_credentials';\n \n const res = await axios.post(\n `https://keycloak.SanctumKey.net/realms/kyc/protocol/openid-connect/token`,\n params,\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n }\n );\n \n cachedToken = res.data.access_token;\n \n if (!cachedToken) {\n throw new Error(\"Keycloak returned a success response but no access_token was found.\");\n }\n\n // Calculate exact expiry timestamp (expires_in is usually in seconds)\n const expiresInMs = (res.data.expires_in || 300) * 1000; \n tokenExpiryTime = Date.now() + expiresInMs;\n\n return cachedToken; \n })();\n\n const finalToken = await activeAuthRequest;\n return finalToken;\n\n } catch (error: any) {\n cachedToken = null; // Clear bad cache\n \n const safeErrorMessage = \n error?.response?.data?.error_description || \n error?.response?.data?.error || \n error?.message || \n 'Unknown network error';\n \n logger.error('Error authentifying:', safeErrorMessage);\n throw new Error(`Échec de l'authentification: ${safeErrorMessage}`);\n \n } finally {\n // 4. Always clear the lock when the request finishes\n activeAuthRequest = null;\n }\n}\n\nexport const errorMessage = (error: any) => {\n return error.response?.data?.message ||\n error.response?.data?.detail ||\n error.response?.data?.error ||\n error.response?.data;\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctum-key/react-native-sdk",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Sanctum Key React Native SDK",
5
5
  "main": "build/src/index.js",
6
6
  "types": "build/src/index.d.ts",
@@ -1,33 +1,35 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { View, StyleSheet, Text, AppState } from 'react-native';
2
+ import { View, StyleSheet, Text, AppState, ActivityIndicator } from 'react-native';
3
3
  import { Camera, useCameraDevice } from 'react-native-vision-camera';
4
4
  import VisionCameraModule from '../modules/camera/VisionCameraModule';
5
5
  import { useI18n } from '../hooks/useI18n';
6
6
  import { EnhancedCameraViewProps } from './OverLay/type';
7
7
  import { Button } from './ui/Button';
8
8
 
9
- export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
9
+ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
10
10
  showCamera,
11
11
  cameraType: initialCameraType = 'front',
12
12
  style,
13
13
  onError,
14
- onSilentCapture,
14
+ onSilentCapture,
15
15
  silentCaptureResult,
16
- isProcessing = false,
16
+ isProcessing = false,
17
17
  overlayComponent,
18
18
  }) => {
19
19
  const { t } = useI18n();
20
20
  const camera = useRef<Camera>(null);
21
-
21
+
22
22
  const isCapturingRef = useRef(false);
23
23
  const isProcessingRef = useRef(isProcessing);
24
24
 
25
25
  const [cameraType] = useState<'front' | 'back'>(initialCameraType);
26
-
27
- // 🚨 BUG FIX: Initialize to null to prevent the "Flicker" on retake
26
+
28
27
  const [hasPermission, setHasPermission] = useState<boolean | null>(null);
29
28
  const [isInitialized, setIsInitialized] = useState(false);
30
29
  const [refreshCamera, setRefreshCamera] = useState(false);
30
+
31
+ // 🚨 ADDED: A timeout state to show a refresh button if the camera gets stuck booting
32
+ const [showInitTimeout, setShowInitTimeout] = useState(false);
31
33
 
32
34
  const device = useCameraDevice(cameraType);
33
35
 
@@ -54,7 +56,10 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
54
56
  };
55
57
 
56
58
  useEffect(() => {
57
- if (showCamera) checkPermissions();
59
+ if (showCamera) {
60
+ setIsInitialized(false); // Reset init state when checking permissions/refreshing
61
+ checkPermissions();
62
+ }
58
63
  }, [showCamera, refreshCamera]);
59
64
 
60
65
  useEffect(() => {
@@ -66,7 +71,26 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
66
71
  return () => subscription.remove();
67
72
  }, [showCamera, hasPermission]);
68
73
 
69
- const onInitialized = useCallback(() => setIsInitialized(true), []);
74
+
75
+ useEffect(() => {
76
+ let timer: ReturnType<typeof setTimeout>;
77
+
78
+ if (hasPermission && device && showCamera && !isInitialized) {
79
+ timer = setTimeout(() => setShowInitTimeout(true), 3000);
80
+ } else {
81
+ setShowInitTimeout(false);
82
+ }
83
+
84
+ return () => {
85
+ if (timer) clearTimeout(timer);
86
+ };
87
+ }, [hasPermission, device, showCamera, isInitialized]);
88
+
89
+ const onInitialized = useCallback(() => {
90
+ setIsInitialized(true);
91
+ setShowInitTimeout(false);
92
+ }, []);
93
+
70
94
  const onCameraError = useCallback((error: any) => {
71
95
  onError?.({ message: error.message || t('camera.errorOccurred') });
72
96
  }, [onError, t]);
@@ -76,30 +100,27 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
76
100
  if (silentCaptureResult?.isAnalyzing) return;
77
101
 
78
102
  try {
79
- isCapturingRef.current = true;
103
+ isCapturingRef.current = true;
80
104
  const photo = await camera.current.takePhoto({
81
- enableShutterSound: false,
82
- flash: 'off',
105
+ enableShutterSound: false,
106
+ flash: 'off',
83
107
  });
84
-
85
108
  const result = await VisionCameraModule.processPhotoResult(photo);
86
-
109
+
87
110
  onSilentCapture?.({
88
- ...result,
89
- path: result.path || photo.path,
111
+ ...result,
112
+ path: result.path || photo.path,
90
113
  });
91
-
92
114
  } catch (error) {
93
115
  // Silent background fail
94
116
  } finally {
95
- isCapturingRef.current = false;
117
+ isCapturingRef.current = false;
96
118
  }
97
119
  }, [isInitialized, onSilentCapture, silentCaptureResult]);
98
120
 
99
- // 🚨 BUG FIX: The Warm-up Timer (Fixes Blurry Images)
100
121
  useEffect(() => {
101
122
  if (!showCamera || !isInitialized || isProcessing) return;
102
-
123
+
103
124
  let isActive = true;
104
125
  let intervalId: ReturnType<typeof setInterval>;
105
126
 
@@ -107,9 +128,9 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
107
128
  if (!isActive) return;
108
129
  intervalId = setInterval(() => {
109
130
  captureSilentPhoto();
110
- }, 1500); // 1.5s gives the hardware more time to stabilize between shots
111
- }, 1000);
112
-
131
+ }, 1500);
132
+ }, 1000);
133
+
113
134
  return () => {
114
135
  isActive = false;
115
136
  clearTimeout(warmupTimer);
@@ -118,40 +139,75 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
118
139
  }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);
119
140
 
120
141
  // --- RENDERERS ---
121
-
122
- // 🚨 BUG FIX: Show nothing while checking permissions (Stops flicker)
142
+
123
143
  if (hasPermission === null) {
124
144
  return <View style={[styles.container, style]} />;
125
145
  }
126
146
 
127
147
  if (hasPermission === false) {
128
148
  return (
129
- <View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>
149
+ <View style={[styles.container, style, styles.centerContent]}>
130
150
  <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>
131
- <Button
132
- title="Refresh Camera"
133
- onPress={() => setRefreshCamera(prev => !prev)}
134
- variant="primary"
151
+ <Button
152
+ title="Refresh Camera"
153
+ onPress={() => setRefreshCamera(prev => !prev)}
154
+ variant="primary"
135
155
  />
136
156
  </View>
137
157
  );
138
158
  }
139
159
 
140
- if (!device || !showCamera) return <View style={[styles.container, style]} />;
160
+ // 🚨 FIX: Don't return an invisible blank screen if the device is loading!
161
+ // Give them a UI and a way out.
162
+ if (!device || !showCamera) {
163
+ return (
164
+ <View style={[styles.container, style, styles.centerContent]}>
165
+ <ActivityIndicator size="large" color="#2DBD60" style={{ marginBottom: 16 }} />
166
+ <Text style={styles.permissionMessage}>Loading Camera Hardware...</Text>
167
+ <Button
168
+ title="Refresh"
169
+ onPress={() => setRefreshCamera(prev => !prev)}
170
+ variant="outline"
171
+ />
172
+ </View>
173
+ );
174
+ }
141
175
 
142
176
  return (
143
177
  <View style={[styles.container, style]}>
144
178
  <Camera
179
+ // 🚨 FIX: This key forces the native component to completely remount
180
+ // when permissions are granted or when manually refreshed.
181
+ key={`cam-${hasPermission}-${refreshCamera ? '1' : '0'}`}
145
182
  ref={camera}
146
183
  style={StyleSheet.absoluteFill}
147
184
  device={device}
148
185
  isActive={showCamera && !isProcessing}
149
186
  photo={true}
150
- video={false}
151
- audio={false}
187
+ video={false}
188
+ audio={false}
152
189
  onInitialized={onInitialized}
153
190
  onError={onCameraError}
154
191
  />
192
+
193
+ {/* 🚨 FIX: Floating Refresh Button if the hardware freezes on a black screen */}
194
+ {!isInitialized && showInitTimeout && (
195
+ <View style={styles.stuckOverlay}>
196
+ <ActivityIndicator size="large" color="#2DBD60" style={{ marginBottom: 16 }} />
197
+ <Text style={{ color: 'white', marginBottom: 16, fontWeight: 'bold' }}>
198
+ Camera is taking a while to start...
199
+ </Text>
200
+ <Button
201
+ title="Restart Camera"
202
+ onPress={() => {
203
+ setIsInitialized(false);
204
+ setRefreshCamera(prev => !prev);
205
+ }}
206
+ variant="primary"
207
+ />
208
+ </View>
209
+ )}
210
+
155
211
  {overlayComponent}
156
212
  </View>
157
213
  );
@@ -159,5 +215,14 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
159
215
 
160
216
  const styles = StyleSheet.create({
161
217
  container: { flex: 1, backgroundColor: 'black' },
162
- permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },
218
+ centerContent: { justifyContent: 'center', alignItems: 'center', padding: 20 },
219
+ permissionMessage: { color: 'white', textAlign: 'center', marginBottom: 20, fontSize: 16, fontWeight: '600' },
220
+ stuckOverlay: {
221
+ ...StyleSheet.absoluteFillObject,
222
+ justifyContent: 'center',
223
+ alignItems: 'center',
224
+ backgroundColor: 'rgba(0,0,0,0.85)',
225
+ zIndex: 1000,
226
+ padding: 20
227
+ }
163
228
  });