ekyc

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

oauth2flow.ts (1911B)


      1 import { UUID } from "#core/domain/uuid.ts";
      2 import { Token } from "#core/domain/token.ts";
      3 import { Ephemeral } from "#core/domain/ephemeral.ts";
      4 import { Scope } from "#core/domain/scope.ts";
      5 import { DomainError } from "#core/domain/error.ts";
      6 import {
      7   isCodeVerifier,
      8   isSafeEqual,
      9   nonceToken,
     10 } from "#core/domain/crypto.ts";
     11 import { ACCESS_TOKEN_TTL, AUTH_CODE_TTL } from "#core/domain/constants.ts";
     12 
     13 export class OAuth2Flow {
     14   constructor(
     15     readonly id: UUID,
     16     readonly clientId: UUID,
     17     readonly scope: Scope,
     18     readonly state: string | null = null,
     19     private _resourceOwner: UUID | null = null,
     20     private _token: Ephemeral<Token> = Ephemeral.empty(),
     21     public version: number = 0,
     22   ) {}
     23 
     24   get resourceOwner() {
     25     return this._resourceOwner;
     26   }
     27 
     28   get token() {
     29     return this._token.valueOf();
     30   }
     31 
     32   get expire() {
     33     return this._token.expire;
     34   }
     35 
     36   get done() {
     37     return this.version >= 3;
     38   }
     39 
     40   authorize(resourceOwner: UUID) {
     41     if (
     42       this.done ||
     43       this.resourceOwner !== null ||
     44       !this._token.isExpired
     45     ) {
     46       throw new InvalidOAuth2Flow();
     47     }
     48 
     49     this._resourceOwner = resourceOwner;
     50     this._token = Ephemeral.of(nonceToken(), AUTH_CODE_TTL);
     51     return this.token!;
     52   }
     53 
     54   accessToken(code: Token) {
     55     if (
     56       this.done ||
     57       this.resourceOwner === null ||
     58       this._token.isExpired ||
     59       !isSafeEqual(this.token, code)
     60     ) {
     61       throw new InvalidOAuth2Flow();
     62     }
     63 
     64     this._token = Ephemeral.of(nonceToken(), ACCESS_TOKEN_TTL);
     65     return this.token!;
     66   }
     67 
     68   authenticate(accessToken: Token): void {
     69     console.log(this, accessToken)
     70     if (
     71       !this.done || !isSafeEqual(this.token, accessToken) ||
     72       this.resourceOwner === null
     73     ) {
     74       throw new InvalidOAuth2Flow();
     75     }
     76   }
     77 }
     78 
     79 export class InvalidOAuth2Flow extends DomainError {
     80   constructor() {
     81     super("Invalid OAuth2 flow");
     82   }
     83 }