import { Controller , Post , Body , BadRequestException , Logger , Get , Param } from '@nestjs/common' ; import { InjectQueue } from '@nestjs/bull' ; import { Queue } from 'bull' ; import { SiopResponseJwt , SiopAckResponse , SiopResponse , SiopRequestJwt } from './dtos/SIOP' ; import { DID_SIOP_ERRORS , LibDidSiopService } from '@lib/did-siop' ; import { CLIENT_ID_URI , BASE_URL } from 'src/Config' ; import { getUserDid , getJwtNonce } from 'src/util/Util' ; import io from 'socket.io-client' ; import Redis from 'ioredis' ; @ Controller ( 'siop' ) export class SiopController { constructor ( @ InjectQueue ( 'siop' ) private readonly siopQueue ) { } private readonly logger = new Logger ( SiopController . name ) ; private readonly nonceRedis = new Redis ( { keyPrefix : "nonce:" } ) ; private readonly jwtRedis = new Redis ( { keyPrefix : "jwt:" } ) ; private readonly socket = io ( BASE_URL ) ; @ Post ( 'responses' ) async validateSIOPResponse ( @ Body ( ) siopResponseJwt ) { this . logger . log ( '[RP Backend] Received POST SIOP Response from SIOP client' ) ; if ( ! siopResponseJwt || ! siopResponseJwt . jwt ) { throw new BadRequestException ( DID_SIOP_ERRORS . INVALID_PARAMS ) ; } this . logger . log ( `[RP Backend] Received SIOP Response JWT: ${ siopResponseJwt . jwt }` ) ; const validationResult = LibDidSiopService . validateSIOPResponse ( siopResponseJwt . jwt , CLIENT_ID_URI , await this . _getValidNonce ( siopResponseJwt . jwt ) ) ; this . logger . debug ( `[RP Backend] SIOP Response validation: ${ validationResult }` ) ; if ( ! validationResult ) { this . logger . error ( DID_SIOP_ERRORS . INVALID_SIOP_RESPONSE ) ; throw new BadRequestException ( DID_SIOP_ERRORS . INVALID_SIOP_RESPONSE ) ; } const siopResponse = { validationResult , did : getUserDid ( siopResponseJwt . jwt ) , jwt : siopResponseJwt . jwt } ; this . socket . emit ( 'sendSignInResponse' , siopResponse ) ; return { validationResult } ; } @ Get ( 'jwts/:clientId' ) async getSIOPRequestJwt ( @ Param ( 'clientId' ) clientId ) { const jwt = await this . jwtRedis . get ( clientId ) ; this . logger . debug ( `Received request from ${ clientId } to get the JWT` ) ; return { jwt } ; } private async _getValidNonce ( jwt ) { const nonce = getJwtNonce ( jwt ) ; try { await this . nonceRedis . get ( getJwtNonce ( jwt ) ) ; } catch ( error ) { this . logger . error ( DID_SIOP_ERRORS . INVALID_PARAMS ) ; throw new BadRequestException ( DID_SIOP_ERRORS . INVALID_PARAMS ) ; } return nonce ; } }