diff --git a/src/modules/identity-provider/identity-provider.controller.ts b/src/modules/identity-provider/identity-provider.controller.ts index de22e1c..c612f4e 100644 --- a/src/modules/identity-provider/identity-provider.controller.ts +++ b/src/modules/identity-provider/identity-provider.controller.ts @@ -153,12 +153,27 @@ export class IdentityProviderController { throw new Error(ErrorCodes.IDENTITY_PROVIDER.INVALID_RESPONSE); } - const origin = req.headers['origin'] as string; + try { + const origin = req.headers['origin'] as string; + this.logger.info('Header Origin: ' + origin); - const lang = language.substring(0, 2) + language.substring(2).toUpperCase(); - const callbackUrl = process.env.ENV !== "prd" ? `${origin}/auth/callback` : `${origin}/${lang}/auth/callback`; + const lang = + language.substring(0, 2) + language.substring(2).toUpperCase(); + const callbackUrl = + process.env.ENV !== 'prd' + ? `${origin}/auth/callback` + : `${origin}/${lang}/auth/callback`; - return await this.identityProviderService.getTokenByIdp(code, state, callbackUrl); + this.logger.info('Callback URL: ' + callbackUrl); + return await this.identityProviderService.getTokenByIdp( + code, + state, + callbackUrl, + ); + } catch (error) { + this.logger.error(error); + throw error; + } } @Get('/links') @@ -166,41 +181,66 @@ export class IdentityProviderController { async providerLinks(@Req() req: Request) { this.logger.info('GET /identity-providers/links'); - const frontDomain = req.headers['origin'] as string; + try { + const frontDomain = req.headers['origin'] as string; + this.logger.info('Header Origin: ' + frontDomain); - if (!frontDomain) { - throw new Error(ErrorCodes.IDENTITY_PROVIDER.INVALID_HEADER); + if (!frontDomain) { + this.logger.info('Not found front domain'); + throw new Error(ErrorCodes.IDENTITY_PROVIDER.INVALID_HEADER); + } + + const result = + await this.identityProviderService.identityProvidersLinksPerDomain( + frontDomain, + ); + return result; + } catch (error) { + this.logger.error(error); + throw error; } - - const result = - await this.identityProviderService.identityProvidersLinksPerDomain( - frontDomain, - ); - return result; } @Get(':id') @HttpCode(HttpStatus.OK) @Redirect() - async loginIdp(@Param('id') id: string, @Req() req: Request, @Language() language: LanguageEnum) { + async loginIdp( + @Param('id') id: string, + @Req() req: Request, + @Language() language: LanguageEnum, + ) { this.logger.info('GET /identity-providers/:id'); + try { + const frontDomain = + (req.headers['origin'] as string) || (req.headers['referer'] as string); + this.logger.info(`Front domain: ${frontDomain}`); + const host = + frontDomain.lastIndexOf('/') !== -1 + ? frontDomain.substring(0, frontDomain.lastIndexOf('/')) + : frontDomain; - const frontDomain = req.headers['origin'] as string || req.headers['referer'] as string; - this.logger.info(`Front domain: ${frontDomain}`); - const host = frontDomain.lastIndexOf('/') !== -1 - ? frontDomain.substring(0, frontDomain.lastIndexOf('/')) - : frontDomain; + const lang = + language.substring(0, 2) + language.substring(2).toUpperCase(); + const callbackUrl = + process.env.ENV !== 'prd' + ? `${host}/auth/callback` + : `${host}/${lang}/auth/callback`; - const lang = language.substring(0, 2) + language.substring(2).toUpperCase(); - const callbackUrl = process.env.ENV !== "prd" ? `${host}/auth/callback` : `${host}/${lang}/auth/callback`; + this.logger.info('Callback URL: ' + callbackUrl); + const redirectUrl = + await this.identityProviderService.loginIdentityProvider( + id, + callbackUrl, + ); - const redirectUrl = - await this.identityProviderService.loginIdentityProvider(id, callbackUrl); - - this.logger.info(`Redirecting to: ${redirectUrl}`); - return { - url: redirectUrl, - }; + this.logger.info(`Redirecting to: ${redirectUrl}`); + return { + url: redirectUrl, + }; + } catch (error) { + this.logger.error(error); + throw error; + } } } diff --git a/src/modules/identity-provider/identity-provider.service.ts b/src/modules/identity-provider/identity-provider.service.ts index 4cca0fe..a2e7084 100644 --- a/src/modules/identity-provider/identity-provider.service.ts +++ b/src/modules/identity-provider/identity-provider.service.ts @@ -14,16 +14,21 @@ import { Metadata } from '@grpc/grpc-js'; import { Issuer, generators } from 'openid-client'; import { SsoSignInDto } from './dto/sso-signin.dto'; import { CacheService } from 'src/services/cache.service'; -import { Request } from 'express'; import { CreateIdentityProvider } from './dto/identity-provider.dto'; +import DadosferaLogger from '@dadosfera/dadosfera-logs'; @Injectable() export class IdentityProviderService implements OnModuleInit { + private logger: DadosferaLogger; private identityProviderService: IdentityProviderProtoService; constructor( @Inject(DucClient.name) private readonly grpcClient: ClientGrpc, private readonly cacheService: CacheService, - ) {} + @Inject(DadosferaLogger) + private dadosferaLoggger: DadosferaLogger + ) { + this.logger = dadosferaLoggger.logger; + } onModuleInit() { this.identityProviderService = @@ -33,22 +38,26 @@ export class IdentityProviderService implements OnModuleInit { } async create(body: IdentityProviderRequest, metadata: Metadata) { + this.logger.info("Call IdentityProvider GRPC Create") return await lastValueFrom( this.identityProviderService.Create(body, metadata), ); } async getList(metadata: Metadata) { + this.logger.info("Call IdentityProvider GRPC GetList") return await lastValueFrom( this.identityProviderService.GetList({}, metadata), ); } async loginIdentityProvider(id: string, callbackUrl: string) { + this.logger.info("Call IdentityProvider GRPC FindIdentityProvider with: " + id); const idp = await lastValueFrom( this.identityProviderService.FindIdentityProvider({ id }), ); + this.logger.info("Discovery issueURL: " + idp.issuerUrl) const issuer = await Issuer.discover(idp.issuerUrl); const client = new issuer.Client({ client_id: idp.clientId, @@ -57,14 +66,19 @@ export class IdentityProviderService implements OnModuleInit { response_types: ['code'], }); + this.logger.info("Generate Challenge") const code_verifier: string = generators.codeVerifier(); const code_challenge: string = generators.codeChallenge(code_verifier); + this.logger.info("Generate State") const state = generators.state(); + + this.logger.info("Generate Nonce") const nonce = generators.nonce(); // Using state because it is returned in the callback // and we can use it to retrieve the code_verifier and nonce + this.logger.info("Save Login parameters in redis") await this.cacheService.set(state, { codeVerifier: code_verifier, nonce, @@ -76,6 +90,7 @@ export class IdentityProviderService implements OnModuleInit { redirectUrls: idp.redirectUrls, }); + this.logger.info("Generate Authorization URL") const url = client.authorizationUrl({ scope: 'openid email', response_type: 'code', @@ -86,16 +101,20 @@ export class IdentityProviderService implements OnModuleInit { redirect_uri: callbackUrl, }); const idpUrl = url + '&identity_provider=' + idp.name; + this.logger.info(idpUrl) return idpUrl; } async getTokenByIdp(code: string, state: string, callbackUrl: string) { + this.logger.info("Get login parameters in redis") const ssoSign = await this.cacheService.get(state); if (!ssoSign) { + this.logger.info("Login Parameters Not Found") throw new BadRequestException('SSO sign-in is expired or not found'); } + this.logger.info("Discovery Issue URL: " + ssoSign.issuerUrl) const issuer = await Issuer.discover(ssoSign.issuerUrl); const client = new issuer.Client({ client_id: ssoSign.clientId, @@ -103,22 +122,22 @@ export class IdentityProviderService implements OnModuleInit { redirect_uris: ssoSign.redirectUrls, }); - if (ssoSign === null) { - throw new BadRequestException('SSO sign-in is expired or not found'); - } - const params = client.callbackParams( `${callbackUrl}?code=${code}&state=${state}`, ); try { + + this.logger.info("Get Token Set"); const tokenSet = await client.callback(callbackUrl, params, { nonce: ssoSign.nonce, code_verifier: ssoSign.codeVerifier, state: ssoSign.state }); + this.logger.info("Delete parameters in redis"); await this.cacheService.delete(ssoSign.state); + this.logger.info("Call IdentityProvider GRPC SignInUser"); return await lastValueFrom( this.identityProviderService.SignInUser({ accessToken: tokenSet.access_token, @@ -128,12 +147,13 @@ export class IdentityProviderService implements OnModuleInit { }), ); } catch (error) { - console.log(error); + this.logger.error(error); throw error; } } async deleteIdentityProvider(id: string, metadata: Metadata) { + this.logger.info("Call IdentityProvider GRPC Delete with: " + id) return await lastValueFrom( this.identityProviderService.DeleteIdentityProvider({ id }, metadata), ); @@ -144,6 +164,7 @@ export class IdentityProviderService implements OnModuleInit { body: CreateIdentityProvider, metadata: Metadata, ) { + this.logger.info("Call IdentityProvider GRPC Update with: " + id) return await lastValueFrom( this.identityProviderService.UpdateIdentityProvider( { @@ -156,6 +177,7 @@ export class IdentityProviderService implements OnModuleInit { } async identityProvidersLinksPerDomain(frontDomain: string) { + this.logger.info("Call IdentityProvider GRPC LinksPerDomain with: " + frontDomain) return await lastValueFrom( this.identityProviderService.GetProviderLinksFromDomain({ frontDomain }), );