@neofaceid/web-sdk 1.13.2 → 1.14.0

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.
@@ -1841,11 +1841,13 @@ const registerPersonWithoutFace = async (personData, applicationToken, options)
1841
1841
  password_confirm: personData.password
1842
1842
  };
1843
1843
  if (documentFrontBase64) {
1844
- body.document_images = [{
1845
- front: documentFrontBase64,
1846
- back: documentBackBase64 || void 0,
1847
- type: (options == null ? void 0 : options.documentType) || "RG"
1848
- }];
1844
+ body.document_images = [
1845
+ {
1846
+ front: documentFrontBase64,
1847
+ back: documentBackBase64 || void 0,
1848
+ type: (options == null ? void 0 : options.documentType) || "RG"
1849
+ }
1850
+ ];
1849
1851
  }
1850
1852
  const response = await fetch(`${getApiBaseUrl()}/api/v1/signup/donor/`, {
1851
1853
  method: "POST",
@@ -1935,11 +1937,13 @@ const registerPersonWithBiometric = async (personData, facePhotos, applicationTo
1935
1937
  face_photos: facePhotosBase64
1936
1938
  };
1937
1939
  if (documentFrontBase64) {
1938
- body.document_images = [{
1939
- front: documentFrontBase64,
1940
- back: documentBackBase64 || void 0,
1941
- type: (options == null ? void 0 : options.documentType) || "RG"
1942
- }];
1940
+ body.document_images = [
1941
+ {
1942
+ front: documentFrontBase64,
1943
+ back: documentBackBase64 || void 0,
1944
+ type: (options == null ? void 0 : options.documentType) || "RG"
1945
+ }
1946
+ ];
1943
1947
  }
1944
1948
  const response = await fetch(`${getApiBaseUrl()}/api/v1/signup/donor/`, {
1945
1949
  method: "POST",
@@ -2322,7 +2326,10 @@ const recordFaceVideo = async (options = {}) => {
2322
2326
  const selectedMimeType = getSupportedMimeType();
2323
2327
  let recorder;
2324
2328
  try {
2325
- recorder = selectedMimeType ? new MediaRecorder(cameraStream, { mimeType: selectedMimeType, videoBitsPerSecond: 1e6 }) : new MediaRecorder(cameraStream, { videoBitsPerSecond: 1e6 });
2329
+ recorder = selectedMimeType ? new MediaRecorder(cameraStream, {
2330
+ mimeType: selectedMimeType,
2331
+ videoBitsPerSecond: 1e6
2332
+ }) : new MediaRecorder(cameraStream, { videoBitsPerSecond: 1e6 });
2326
2333
  } catch {
2327
2334
  recorder = new MediaRecorder(cameraStream);
2328
2335
  }
@@ -2495,6 +2502,68 @@ const videoToBase64 = async (videoBlob) => {
2495
2502
  reader.readAsDataURL(videoBlob);
2496
2503
  });
2497
2504
  };
2505
+ const blobToBase64 = (blob) => new Promise((resolve, reject) => {
2506
+ const reader = new FileReader();
2507
+ reader.onload = () => {
2508
+ const result = reader.result;
2509
+ resolve(result.includes(",") ? result.split(",")[1] : result);
2510
+ };
2511
+ reader.onerror = () => reject(new NeoFaceError("Failed to convert image to base64", ErrorType.CAPTURE_ERROR));
2512
+ reader.readAsDataURL(blob);
2513
+ });
2514
+ const registerDocumentByImage = async (personId, jwtToken, images) => {
2515
+ var _a, _b;
2516
+ ensureSecureContext();
2517
+ if (!personId) {
2518
+ throw new NeoFaceError("personId is required", ErrorType.VALIDATION_ERROR);
2519
+ }
2520
+ if (!jwtToken) {
2521
+ throw new NeoFaceError("jwtToken is required", ErrorType.VALIDATION_ERROR);
2522
+ }
2523
+ if (!images || images.length === 0) {
2524
+ throw new NeoFaceError("At least one document image is required", ErrorType.VALIDATION_ERROR);
2525
+ }
2526
+ const base64Images = await Promise.all(
2527
+ images.map(async (img) => {
2528
+ const compressed = await compressDocumentImage(img);
2529
+ return blobToBase64(compressed);
2530
+ })
2531
+ );
2532
+ const controller = createTimeoutController();
2533
+ try {
2534
+ const response = await fetch(`${getApiBaseUrl()}/api/v1/donors/${personId}/documents/`, {
2535
+ method: "POST",
2536
+ headers: {
2537
+ "Content-Type": "application/json",
2538
+ Authorization: `Bearer ${jwtToken}`
2539
+ },
2540
+ body: JSON.stringify({ document_images: base64Images }),
2541
+ signal: controller.signal
2542
+ });
2543
+ const data = await response.json();
2544
+ if (!response.ok) {
2545
+ throw new NeoFaceError(
2546
+ (data == null ? void 0 : data.message) || `API Error ${response.status}`,
2547
+ ErrorType.NETWORK_ERROR
2548
+ );
2549
+ }
2550
+ return {
2551
+ success: true,
2552
+ taskId: ((_a = data.data) == null ? void 0 : _a.task_id) ?? "",
2553
+ status: ((_b = data.data) == null ? void 0 : _b.status) ?? "processing",
2554
+ message: data.message ?? "Documents submitted for processing"
2555
+ };
2556
+ } catch (error) {
2557
+ if (error instanceof NeoFaceError) throw error;
2558
+ if (error instanceof Error) {
2559
+ if (error.name === "AbortError") {
2560
+ throw new NeoFaceError("Request timeout", ErrorType.NETWORK_ERROR);
2561
+ }
2562
+ throw new NeoFaceError(error.message, ErrorType.NETWORK_ERROR);
2563
+ }
2564
+ throw new NeoFaceError("Unknown error occurred", ErrorType.NETWORK_ERROR);
2565
+ }
2566
+ };
2498
2567
  const modalReducer$1 = (state, action) => {
2499
2568
  switch (action.type) {
2500
2569
  case "PERMISSION_GRANTED":
@@ -6034,8 +6103,8 @@ const biometricDetection = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.
6034
6103
  initializeBiometricDetection,
6035
6104
  isAdvancedDetectionAvailable
6036
6105
  }, Symbol.toStringTag, { value: "Module" }));
6037
- const VERSION = "1.13.2";
6038
- const RELEASE_DATE = "2026-02-21";
6106
+ const VERSION = "1.14.0";
6107
+ const RELEASE_DATE = "2026-03-04";
6039
6108
  class OnboardingCaptureModal {
6040
6109
  constructor(options) {
6041
6110
  __publicField(this, "overlay", null);
@@ -6494,6 +6563,47 @@ class NeoFaceID {
6494
6563
  * }
6495
6564
  * ```
6496
6565
  */
6566
+ /**
6567
+ * Registers document images for an already-registered donor person.
6568
+ *
6569
+ * Opens the document capture UI (front + optional back), then submits
6570
+ * the images to the backend for extraction via DocExt.
6571
+ * The backend processes this asynchronously — use the returned `taskId`
6572
+ * to poll status if needed.
6573
+ *
6574
+ * @param personId UUID of the donor's person record
6575
+ * @param jwtToken JWT Bearer token of the authenticated donor
6576
+ * @param options Optional capture configuration
6577
+ * @returns Promise with task_id and processing status
6578
+ * @throws NeoFaceError if capture is cancelled, validation fails, or API call fails
6579
+ *
6580
+ * @example
6581
+ * ```typescript
6582
+ * const sdk = new NeoFaceID({ appToken: 'your-token' });
6583
+ *
6584
+ * const result = await sdk.registerDocumentByImage(personId, userJwtToken);
6585
+ * console.log('Task ID:', result.taskId); // poll for completion
6586
+ * ```
6587
+ */
6588
+ async registerDocumentByImage(personId, jwtToken, options = {}) {
6589
+ const { DocumentCaptureModal: DocumentCaptureModal2 } = await Promise.resolve().then(() => DocumentCaptureModal$1);
6590
+ const modal = new DocumentCaptureModal2({
6591
+ useBackCamera: options.useBackCamera ?? true,
6592
+ preSelectedDocument: options.preSelectedDocument
6593
+ });
6594
+ const captureResult = await modal.open();
6595
+ if (!captureResult.success || !captureResult.frontImage) {
6596
+ throw new NeoFaceError(
6597
+ captureResult.error === "cancelled" ? "Document capture was cancelled by the user" : `Document capture failed: ${captureResult.error ?? "unknown error"}`,
6598
+ ErrorType.CAPTURE_ERROR
6599
+ );
6600
+ }
6601
+ const images = [captureResult.frontImage];
6602
+ if (captureResult.backImage) {
6603
+ images.push(captureResult.backImage);
6604
+ }
6605
+ return registerDocumentByImage(personId, jwtToken, images);
6606
+ }
6497
6607
  async proofOfLife(options = {}) {
6498
6608
  const {
6499
6609
  videoDurationMs = 3e3,
@@ -7672,6 +7782,11 @@ const startDocumentCapture = async (options) => {
7672
7782
  const modal = new DocumentCaptureModal(options);
7673
7783
  return modal.open();
7674
7784
  };
7785
+ const DocumentCaptureModal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
7786
+ __proto__: null,
7787
+ DocumentCaptureModal,
7788
+ startDocumentCapture
7789
+ }, Symbol.toStringTag, { value: "Module" }));
7675
7790
  function start(applicationToken, callbacks) {
7676
7791
  const container = document.createElement("div");
7677
7792
  container.id = "neoface-modal-container";