initiate.ts (1856B)
1 import { ClientRepository } from "#core/application/oauth2/client_repository.ts"; 2 import { OAuth2FlowRepository } from "#core/application/oauth2/flow_repository.ts"; 3 import { RateLimitRepository } from "#core/application/oauth2/ratelimit_repository.ts"; 4 import { InvalidOAuth2Flow } from "#core/domain/oauth2flow.ts"; 5 import { InvalidUUID, UUID } from "#core/domain/uuid.ts"; 6 import { EntityLocked, EntityNotFound } from "../repository_error.ts"; 7 8 export type OAuth2FlowInitiateRequest = { 9 clientId: string; 10 scope: string | null; 11 state: string | null; 12 ip: string; 13 }; 14 15 export type OAuth2FlowInitiateResponse = { 16 initiated: boolean; 17 uuid: string | null; 18 scope: string[]; 19 }; 20 21 export class OAuth2FlowInitiateUseCase { 22 constructor( 23 private readonly clientRepo: ClientRepository, 24 private readonly flowRepo: OAuth2FlowRepository, 25 private readonly rateLimitRepo: RateLimitRepository, 26 ) {} 27 28 async execute( 29 request: OAuth2FlowInitiateRequest, 30 ): Promise<OAuth2FlowInitiateResponse> { 31 try { 32 const clientId = new UUID(request.clientId); 33 const client = await this.clientRepo.find(clientId); 34 const rateLimit = await this.rateLimitRepo.findOrCreate(request.ip); 35 rateLimit.increment(); 36 await this.rateLimitRepo.store(rateLimit); 37 const flow = client.inititate(request.scope, request.state); 38 await this.flowRepo.store(flow); 39 return { 40 initiated: true, 41 uuid: flow.id.toString(), 42 scope: flow.scope.values, 43 }; 44 } catch (error) { 45 if ( 46 error instanceof InvalidUUID || 47 error instanceof EntityNotFound || 48 error instanceof EntityLocked || 49 error instanceof InvalidOAuth2Flow 50 ) { 51 return { 52 initiated: false, 53 uuid: null, 54 scope: [], 55 }; 56 } 57 throw error; 58 } 59 } 60 }