ekyc

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

email_challenge.ts (1654B)


      1 import { AuthRepository } from "#core/application/authn/auth_repository.ts";
      2 import { EntityNotFound } from "../repository_error.ts";
      3 import { AlreadyVerifiedCodeChallenge } from "#core/domain/code_challenge.ts";
      4 import { ExceedingLimit } from "#core/domain/limiter.ts";
      5 import { InvalidUUID, UUID } from "#core/domain/uuid.ts";
      6 
      7 export type AuthEmailChallengeRequest = {
      8   uuid: string;
      9 };
     10 
     11 export type AuthEmailChallengeResponse = {
     12   status: "sent" | "invalid" | "verified",
     13   delay: number
     14 }
     15 
     16 export interface AuthEmailChallengeMailer {
     17   send(email: string, code: string): Promise<void> | void;
     18 }
     19 
     20 export class AuthEmailChallengeUseCase {
     21   constructor(
     22     private readonly repo: AuthRepository,
     23     private readonly mailer: AuthEmailChallengeMailer,
     24   ) {
     25   }
     26 
     27   async execute(
     28     request: AuthEmailChallengeRequest,
     29   ): Promise<AuthEmailChallengeResponse> {
     30     try {
     31       const uuid = new UUID(request.uuid);
     32       const auth = await this.repo.find(uuid);
     33       const code = auth.requestEmailChallenge();
     34       await this.repo.store(auth);
     35       await this.mailer.send(
     36         auth.email.address.toString(),
     37         code.toString(),
     38       );
     39       return { status: "sent", delay: auth.email.requestDelay };
     40     } catch (error) {
     41       if (error instanceof ExceedingLimit) {
     42         return { status: "sent", delay: error.delay };
     43       }
     44       if (
     45         error instanceof InvalidUUID ||
     46         error instanceof EntityNotFound
     47       ) {
     48         return { status: "invalid", delay: 0 };
     49       }
     50       if (error instanceof AlreadyVerifiedCodeChallenge) {
     51         return { status: "verified", delay: 0 };
     52       }
     53       throw error;
     54     }
     55   }
     56 }