ekyc

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

register.ts (1971B)


      1 import { PhoneRepository } from "#core/application/phone/phone_repository.ts";
      2 import { EntityLocked } from "#core/application/repository_error.ts";
      3 import { AlreadyVerifiedCodeChallenge } from "#core/domain/code_challenge.ts";
      4 import { ExceedingLimit } from "#core/domain/limiter.ts";
      5 import {
      6   InvalidPersonalPhoneNumber,
      7   PersonalPhoneNumber,
      8 } from "#core/domain/personal_phone_number.ts";
      9 import { UUID } from "#core/domain/uuid.ts";
     10 
     11 export type PhoneRegisterRequest = {
     12   uuid: string;
     13   phoneNumber: string;
     14 };
     15 
     16 export type PhoneRegisterResponse = {
     17   status: "sent" | "invalid" | "conflict" | "verified";
     18   delay: number;
     19 };
     20 
     21 export interface PhoneSmsChallengeSender {
     22   send(phoneNumber: string, code: string): Promise<void> | void;
     23 }
     24 
     25 export class PhoneRegisterUseCase {
     26   constructor(
     27     private readonly phoneRepo: PhoneRepository,
     28     private readonly sender: PhoneSmsChallengeSender,
     29   ) {
     30   }
     31 
     32   async execute(
     33     request: PhoneRegisterRequest,
     34   ): Promise<PhoneRegisterResponse> {
     35     try {
     36       const uuid = new UUID(request.uuid);
     37       const phoneNumber = new PersonalPhoneNumber(request.phoneNumber);
     38       const phone = await this.phoneRepo.findOrCreate(uuid);
     39       const code = phone.requestSmsChallenge(phoneNumber);
     40       await this.phoneRepo.store(phone);
     41       await this.sender.send(
     42         phoneNumber.toString(),
     43         code.toString(),
     44       );
     45       return {
     46         status: "sent",
     47         delay: phone.smsChallenge.requestDelay,
     48       };
     49     } catch (error) {
     50       if (error instanceof AlreadyVerifiedCodeChallenge) {
     51         return { status: "verified", delay: 0 };
     52       }
     53       if (error instanceof InvalidPersonalPhoneNumber) {
     54         return { status: "invalid", delay: 0 };
     55       }
     56       if (error instanceof EntityLocked) {
     57         return { status: "conflict", delay: 0 };
     58       }
     59       if (error instanceof ExceedingLimit) {
     60         return { status: "sent", delay: error.delay };
     61       }
     62       throw error;
     63     }
     64   }
     65 }