import { ClassTransformOptions } from 'class-transformer' ; import { ValidatorOptions } from 'class-validator' ; import { Body , Controller , Get , Post , Redirect , Render , Req , Res , UsePipes , ValidationPipe , } from '@nestjs/common' ; import { PartialExcept , validateDto } from '@fc/common' ; import { ConfigService } from '@fc/config' ; import { EidasClientSession } from '@fc/eidas-client' ; import { EidasCountryService } from '@fc/eidas-country' ; import { EidasToOidcService , OidcToEidasService } from '@fc/eidas-oidc-mapper' ; import { LoggerLevelNames , LoggerService } from '@fc/logger' ; import { IOidcIdentity , OidcError } from '@fc/oidc' ; import { OidcClientSession } from '@fc/oidc-client' ; import { OidcProviderService } from '@fc/oidc-provider' ; import { ISessionService , Session , SessionService } from '@fc/session' ; import { AppConfig , EidasBridgeIdentityDto , EidasBridgeValidateEuropeanIdentity , } from '../dto' ; import { EidasBridgeRoutes } from '../enums' ; import { EidasBridgeInvalidIdentityException } from '../exceptions' ; todo see https @ Controller ( ) export class EuIdentityToFrController { constructor ( private readonly config , private readonly logger , private readonly oidcProvider , private readonly oidcToEidas , private readonly eidasToOidc , private readonly eidasCountry , private readonly sessionService ) { this . logger . setContext ( this . constructor . name ) ; } TODO see https @ Get ( EidasBridgeRoutes . INTERACTION ) @ UsePipes ( new ValidationPipe ( { whitelist : true } ) ) @ Render ( 'interaction' ) async getInteraction ( @ Req ( ) req , @ Res ( ) res , @ Session ( 'EidasClient' ) sessionEidas , todo author Hugues
     *  date ticket @ Session ( 'OidcClient' ) sessionOidc ) { const { uid , params } = await this . oidcProvider . getInteraction ( req , res ) ; const { countryIsoList } = await this . config . get < AppConfig > ( 'App' ) ; const { spName } = await sessionOidc . get ( ) ; const eidasPartialRequest = this . oidcToEidas . mapPartialRequest ( params . scope , params . acr_values ) ; await sessionEidas . set ( 'eidasPartialRequest' , eidasPartialRequest ) ; const countryList = await this . eidasCountry . getListByIso ( countryIsoList ) ; const response = { countryList , uid , params , spName , } ; this . logger . trace ( { route : EidasBridgeRoutes . INTERACTION , method : 'GET' , name : 'EidasBridgeRoutes.INTERACTION' , response , } ) ; return response ; } todo see https @ Post ( EidasBridgeRoutes . INTERACTION_LOGIN ) @ UsePipes ( new ValidationPipe ( { whitelist : true } ) ) @ Redirect ( ) async redirectToFrNodeConnector ( @ Body ( ) body ) { const response = { url : `/eidas-client/redirect-to-fr-node-connector?country=${ body . country }` , statusCode : 302 , } ; this . logger . trace ( { route : EidasBridgeRoutes . INTERACTION_LOGIN , method : 'POST' , name : 'EidasBridgeRoutes.INTERACTION_LOGIN' , response , } ) ; return response ; } @ Get ( EidasBridgeRoutes . FINISH_FC_INTERACTION ) async finishInteraction ( @ Req ( ) req , @ Res ( ) res , todo author Hugues
     *  date ticket @ Session ( 'OidcClient' ) sessionOidc , @ Session ( 'EidasClient' ) sessionEidas ) { const { eidasResponse } = await sessionEidas . get ( ) ; if ( eidasResponse . status . failure ) { const { params } = await this . oidcProvider . getInteraction ( req , res ) ; const oidcError = await this . eidasToOidc . mapPartialResponseFailure ( eidasResponse ) ; return res . redirect ( this . buildRedirectUriErrorUrl ( params , oidcError ) ) ; } const { acr , userinfos : idpIdentity } = this . eidasToOidc . mapPartialResponseSuccess ( eidasResponse ) ; await this . validateIdentity ( idpIdentity ) ; const spIdentity = idpIdentity ; /**
         * We need to set an alias with the sub since later (findAccount) we do not have access
         * to the sessionId, nor the interactionId.
         */ await this . sessionService . setAlias ( spIdentity . sub , req . sessionId ) ; const idpIdentityReset = { sub : idpIdentity . sub , } ; const session = { idpIdentity : idpIdentityReset , spIdentity , spAcr : acr , } ; await sessionOidc . set ( session ) ; const sessionClient = await sessionOidc . get ( ) ; this . logger . trace ( { route : EidasBridgeRoutes . FINISH_FC_INTERACTION , method : 'GET' , name : 'EidasBridgeRoutes.FINISH_FC_INTERACTION' , session , } ) ; return this . oidcProvider . finishInteraction ( req , res , sessionClient ) ; } param identity private async validateIdentity ( identity ) { const validatorOptions = { whitelist : true , forbidNonWhitelisted : true , forbidUnknownValues : true , } ; const transformOptions = { excludeExtraneousValues : true , } ; const errors = await validateDto ( identity , EidasBridgeIdentityDto , validatorOptions , transformOptions ) ; if ( errors . length ) { this . logger . trace ( { errors } , LoggerLevelNames . WARN ) ; throw new EidasBridgeInvalidIdentityException ( ) ; } } private buildRedirectUriErrorUrl ( params , oidcError ) { const { error , error_description : errorDescription } = oidcError ; return `${ params . redirect_uri }?error=${ encodeURIComponent ( error ) }&error_description=${ encodeURIComponent ( errorDescription ) }&state=${ encodeURIComponent ( params . state ) }` ; } }