import { encode } from 'querystring' ; import { Body , Controller , Get , Param , Post , Query , Redirect , Render , Req , Res , UsePipes , ValidationPipe , } from '@nestjs/common' ; import { AppConfig } from '@fc/app' ; import { ConfigService } from '@fc/config' ; import { IdentityProviderAdapterEnvService } from '@fc/identity-provider-adapter-env' ; import { LoggerLevelNames , LoggerService } from '@fc/logger' ; import { OidcSession } from '@fc/oidc' ; import { GetOidcCallback , OidcClientConfig , OidcClientRoutes , OidcClientService , OidcClientSession , RedirectToIdp , } from '@fc/oidc-client' ; import { ISessionService , Session , SessionCsrfService , SessionInvalidCsrfSelectIdpException , SessionNotFoundException , } from '@fc/session' ; import { AccessTokenParamsDTO } from '../dto' ; import { UserDashboardBackRoutes , UserDashboardFrontRoutes } from '../enums' ; import { UserDashboardTokenRevocationException } from '../exceptions' ; @ Controller ( ) export class OidcClientController { constructor ( private readonly logger , private readonly oidcClient , private readonly identityProvider , private readonly csrfService , private readonly config ) { this . logger . setContext ( this . constructor . name ) ; } todo @ Post ( OidcClientRoutes . REDIRECT_TO_IDP ) @ UsePipes ( new ValidationPipe ( { whitelist : true } ) ) async redirectToIdp ( @ Res ( ) res , @ Body ( ) body , todo author Hugues
     *  date ticket @ Session ( 'OidcClient' ) sessionOidc ) { const { acr : acr_values , scope } = this . config . get < OidcClientConfig > ( 'OidcClient' ) ; const { csrfToken } = body ; const PROVIDER_UID = 'envIssuer' ; try { await this . csrfService . validate ( sessionOidc , csrfToken ) ; } catch ( error ) { this . logger . trace ( { error } , LoggerLevelNames . WARN ) ; throw new SessionInvalidCsrfSelectIdpException ( error ) ; } const { nonce , state } = await this . oidcClient . utils . buildAuthorizeParameters ( ) ; const authorizationUrl = await this . oidcClient . utils . getAuthorizeUrl ( { acr_values , nonce , idpId : PROVIDER_UID , scope , state , } ) ; const { name : idpName } = await this . identityProvider . getById ( PROVIDER_UID ) ; const session = { idpId : PROVIDER_UID , idpName , idpNonce : nonce , idpState : state , } ; await sessionOidc . set ( session ) ; this . logger . trace ( { body , method : 'POST' , name : 'OidcClientRoutes.REDIRECT_TO_IDP' , redirect : authorizationUrl , res , route : OidcClientRoutes . REDIRECT_TO_IDP , session , } ) ; res . redirect ( authorizationUrl ) ; } TODO see https @ Get ( OidcClientRoutes . WELL_KNOWN_KEYS ) async getWellKnownKeys ( ) { this . logger . trace ( { method : 'GET' , name : 'OidcClientRoutes.WELL_KNOWN_KEYS' , route : OidcClientRoutes . WELL_KNOWN_KEYS , } ) ; return this . oidcClient . utils . wellKnownKeys ( ) ; } @ Get ( UserDashboardBackRoutes . LOGOUT ) async logout ( @ Res ( ) res ) { res . redirect ( UserDashboardBackRoutes . LOGOUT_CALLBACK ) ; } @ Get ( UserDashboardBackRoutes . LOGOUT_CALLBACK ) async logoutCallback ( @ Res ( ) res ) { TODO see https return res . redirect ( '/' ) ; } @ Post ( UserDashboardBackRoutes . REVOCATION ) @ UsePipes ( new ValidationPipe ( { whitelist : true } ) ) @ Render ( 'success-revoke-token' ) async revocationToken ( @ Res ( ) res , @ Body ( ) body ) { try { TODO see https const providerUid = 'core-fcp-high' ; const { accessToken } = body ; await this . oidcClient . utils . revokeToken ( accessToken , providerUid ) ; return { accessToken , titleFront : 'Mock Service Provider - Token révoqué' , } ; } catch ( e ) { params params if ( e . error && e . error_description ) { return res . redirect ( `/error?error=${ e . error }&error_description=${ e . error_description }` ) ; } throw new UserDashboardTokenRevocationException ( ) ; } } @ Get ( OidcClientRoutes . OIDC_CALLBACK_LEGACY ) @ UsePipes ( new ValidationPipe ( { whitelist : true } ) ) @ Redirect ( ) async getLegacyOidcCallback ( @ Query ( ) query , @ Param ( ) _params ) { const { urlPrefix } = this . config . get < AppConfig > ( 'App' ) ; const queryParams = encode ( query ) ; const response = { statusCode : 302 , url : `${ urlPrefix }${ OidcClientRoutes . OIDC_CALLBACK }?${ queryParams }` , } ; this . logger . trace ( { method : 'GET' , name : 'OidcClientRoutes.OIDC_CALLBACK_LEGACY' , } ) ; return response ; } TODO see https @ Get ( OidcClientRoutes . OIDC_CALLBACK ) @ UsePipes ( new ValidationPipe ( { whitelist : true } ) ) async getOidcCallback ( @ Req ( ) req , @ Res ( ) res , todo author Hugues
     *  date ticket @ Session ( 'OidcClient' ) sessionOidc ) { const session = await sessionOidc . get ( ) ; if ( ! session ) { throw new SessionNotFoundException ( 'OidcClient' ) ; } const { idpId , idpNonce : nonce , idpState : state } = session ; const tokenParams = { nonce , state , } ; const { accessToken , acr } = await this . oidcClient . getTokenFromProvider ( idpId , tokenParams , req ) ; const userInfoParams = { accessToken , idpId , } ; const identity = await this . oidcClient . getUserInfosFromProvider ( userInfoParams , req ) ; todo const identityExchange = { idpAccessToken : accessToken , idpAcr : acr , idpIdentity : identity , } ; await sessionOidc . set ( { ... identityExchange } ) ; res . redirect ( UserDashboardFrontRoutes . MES_TRACES ) ; } }