ekyc

Electronic KYC process with uploading ID document using OAuth 2.1 (experimental)
Log | Files | Refs | README | LICENSE

capture.ts (2034B)


      1 import { EntityLocked } from "#core/application/repository_error.ts";
      2 
      3 import { IDDocumentRepository } from "#core/application/id_document/id_document_repository.ts";
      4 import {
      5   IDDocumentMRZScan,
      6   MRZInfo,
      7 } from "#core/application/id_document/mrzscan.ts";
      8 import { IDDocumentOutOfState } from "#core/domain/id_document.ts";
      9 import { Picture } from "#core/domain/picture.ts";
     10 import { InvalidUUID, UUID } from "#core/domain/uuid.ts";
     11 
     12 export type IDDocumentCaptureRequest = {
     13   uuid: string;
     14   side: "doc-front" | "doc-back" | "face-left" | "face-front" | "face-right";
     15   picture: string;
     16 };
     17 
     18 export type IDDocumentCaptureResponse = {
     19   status: "invalid" | "scanned" | "scan-failure" | "captured";
     20 } & MRZInfo;
     21 
     22 export class IDDocumentCaptureUseCase {
     23   constructor(
     24     private readonly idDocumentRepo: IDDocumentRepository,
     25     private readonly scanner: IDDocumentMRZScan,
     26   ) {
     27   }
     28 
     29   async execute(
     30     request: IDDocumentCaptureRequest,
     31   ): Promise<IDDocumentCaptureResponse> {
     32     let info: MRZInfo = {
     33       firstName: null,
     34       lastName: null,
     35       birthDate: null,
     36       sex: null,
     37       nationality: null,
     38       country: null,
     39     };
     40     try {
     41       const uuid = new UUID(request.uuid);
     42       const picture = new Picture(request.picture);
     43       const idDocument = await this.idDocumentRepo.findOrCreate(uuid);
     44 
     45       try {
     46         if (request.side === "doc-back") {
     47           info = await this.scanner.scan(picture.toString());
     48         }
     49       } catch {
     50         return {
     51           status: "scan-failure",
     52           ...info,
     53         };
     54       }
     55 
     56       idDocument.capture(request.side, picture, info);
     57 
     58       await this.idDocumentRepo.store(idDocument);
     59       return {
     60         status: request.side === "doc-back" ? "scanned" : "captured",
     61         ...info,
     62       };
     63     } catch (error) {
     64       if (
     65         error instanceof InvalidUUID ||
     66         error instanceof IDDocumentOutOfState ||
     67         error instanceof EntityLocked
     68       ) {
     69         return { status: "invalid", ...info };
     70       }
     71       throw error;
     72     }
     73   }
     74 }