import * as _ from 'lodash' ; import { Injectable } from '@nestjs/common' ; import { CogService } from '@fc/cog' ; import { EidasAttributes , EidasPartialRequest , EidasResponse , EidasResponseAttributes , EidasStatusCodes , EidasSubStatusCodes , } from '@fc/eidas' ; import { LoggerService } from '@fc/logger' ; import { AcrValues , OidcError } from '@fc/oidc' ; import { IOidcIdentity } from '../interfaces' ; import { AcrValuesToLevelOfAssurancesMap , ClaimsToAttributesMap , ScopesToRequestedAttributesMap , } from '../mappers' ; @ Injectable ( ) export class OidcToEidasService { constructor ( private readonly logger , private readonly eidasCog ) { logger . setContext ( this . constructor . name ) ; } mapPartialRequest ( requestedScopes , acr ) { this . logger . debug ( 'mapPartialRequest()' ) ; const scopes = requestedScopes . split ( ' ' ) ; const requestedAttributesSet = this . mapScopesToRequestedAttributes ( scopes ) ; const requestedAttributes = Array . from ( requestedAttributesSet ) ; this . logger . trace ( { requestedAttributes , requestedScopes } ) ; return { levelOfAssurance : AcrValuesToLevelOfAssurancesMap [ acr ] , requestedAttributes , } ; } param claims param acr param requestedAttributes return async mapPartialResponseSuccess ( claims , acr , requestedAttributes ) { this . logger . debug ( 'mapPartialResponseSuccess()' ) ; const attributes = this . mapRequestedAttributesFromClaims ( claims , requestedAttributes ) ; const cogs = attributes [ EidasAttributes . PLACE_OF_BIRTH ] ; if ( cogs && cogs . length ) { attributes [ EidasAttributes . PLACE_OF_BIRTH ] = await this . eidasCog . injectLabelsForCogs ( cogs ) ; } const subject = claims . sub ; const levelOfAssurance = AcrValuesToLevelOfAssurancesMap [ acr ] ; this . logger . trace ( { attributes , levelOfAssurance , subject } ) ; return { attributes , levelOfAssurance , status : { failure : false , statusCode : EidasStatusCodes . SUCCESS , } , subject , } ; } param error return mapPartialResponseFailure ( error ) { let errorToReturn ; todo see https if ( error instanceof Error ) { errorToReturn = { error : 'internal_error' , error_description : 'FranceConnect encountered an unexpected error, please contact the support (Code Y000000).' , } ; this . logger . error ( error ) ; } else { errorToReturn = error ; } return { status : { failure : true , statusCode : EidasStatusCodes . RESPONDER , statusMessage : `[${ errorToReturn . error }]: ${ errorToReturn . error_description }` , subStatusCode : EidasSubStatusCodes . AUTHN_FAILED , } , } ; } param claims param requestedAttributes return private mapRequestedAttributesFromClaims ( claims , requestedAttributes ) { return requestedAttributes . reduce ( this . getClaimsBoundedClaimsToAttributesReducer ( claims ) , { } ) ; } param claims return private getClaimsBoundedClaimsToAttributesReducer ( claims ) { return this . claimsToAttributesReducer . bind ( OidcToEidasService , claims ) ; } param claims param attributes param requestedAttributes return private claimsToAttributesReducer ( claims , attributes , requestedAttribute ) { if ( ClaimsToAttributesMap [ requestedAttribute ] ) { attributes [ requestedAttribute ] = ClaimsToAttributesMap [ requestedAttribute ] ( claims ) ; } return attributes ; } param oidcScopes return private mapScopesToRequestedAttributes ( oidcScopes ) { see https const scopesSet = new Set < EidasAttributes > ( [ EidasAttributes . PERSON_IDENTIFIER , EidasAttributes . CURRENT_GIVEN_NAME , EidasAttributes . CURRENT_FAMILY_NAME , EidasAttributes . DATE_OF_BIRTH , ] ) ; return oidcScopes . reduce ( this . scopesToRequestedAttributesReducer , scopesSet ) ; } param attributesSet param scope return private scopesToRequestedAttributesReducer ( attributesSet , scope ) { if ( ScopesToRequestedAttributesMap [ scope ] ) { ScopesToRequestedAttributesMap [ scope ] . forEach ( ( attribute ) => { attributesSet . add ( attribute ) ; } ) ; } return attributesSet ; } }