import { OnModuleInit, Inject, Injectable, ForbiddenException } from '@nestjs/common'; import { ClientGrpc } from '@nestjs/microservices'; import { DadosferaLogger } from '@dadosfera/dadosfera-logs'; import { lastValueFrom } from 'rxjs'; import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc'; import { AuthProtoService as AuthServiceInterface, IdentityProviderProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service'; import { AuthSnowflakeSignInRequest, AuthSignInRequest, AuthRefreshAccessTokenRequest, AuthEnableTotpMfaRequest, AuthDisableTotpMfaRequest, AuthDismissTotpMfaRequest, AuthVerifyTotpMfaRequest, AuthChangePasswordRequest, AuthResetPasswordRequest, AuthVerifyResetPasswordCodeRequest, AuthConfirmResetPasswordRequest, AuthSignInResponse, } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; import { DucClient } from '../duc/client.config'; import { Metadata } from '@grpc/grpc-js'; import { BulkEditResponse } from './dtos/login'; @Injectable() export class AuthClientService implements OnModuleInit { logger: DadosferaLogger; private authService: AuthServiceInterface; private identityProviderService: IdentityProviderProtoService; constructor( @Inject(DadosferaLogger) dadosferaLogger: DadosferaLogger, @Inject(DucClient.name) private readonly grpcClient: ClientGrpc, ) { this.logger = dadosferaLogger.logger; } onModuleInit() { this.authService = this.grpcClient.getService( ProtoServices.AuthProtoService, ); this.identityProviderService = this.grpcClient.getService( ProtoServices.IdentityProviderProtoService, ); } async getPublicKeys() { this.logger.info('GetPublicKeys'); return lastValueFrom(this.authService.AuthGetPublicKeys({})); } async snowflakeSignIn(input: AuthSnowflakeSignInRequest) { this.logger.info('snowflakeSignIn'); return lastValueFrom(this.authService.AuthSnowflakeSignIn(input)); } checkDedicatedProxy({ customer }: AuthSignInResponse) { const DEDICATED_PROXY = process.env.DEDICATED_PROXY || ''; this.logger.info('SignIn - Setting customer ID for dedicated proxy: ' + DEDICATED_PROXY); this.logger.info('Customer ID: ' + customer.id); if (DEDICATED_PROXY !== '' && DEDICATED_PROXY !== customer.id) { throw new ForbiddenException(); } // Bloquear o customer de acesso o maestro publico this.logger.info('Check if customer have network policy: ' + customer.modules); const hasNetworkPolicyModule = customer.modules.includes('network-policy'); if (hasNetworkPolicyModule && DEDICATED_PROXY === '') { throw new ForbiddenException(); } } async signIn( { username, password, totp }: AuthSignInRequest, metadata: Metadata, ) { this.logger.info('SignIn'); let result: AuthSignInResponse; try { result = await lastValueFrom( this.authService.AuthSignIn({ username, password, totp }, metadata), ); } catch (error) { this.logger.error('SignIn - Error during sign-in'); this.logger.error(error); throw error; } if (result.customer) { this.checkDedicatedProxy(result); } return result } async refreshAccessToken( { refreshToken, userId }: AuthRefreshAccessTokenRequest, metadata: Metadata, ) { this.logger.info('RefreshAccessToken'); return lastValueFrom( this.authService.AuthRefreshAccessToken({ refreshToken, userId }, metadata), ); } async changePassword({ accessToken, oldPassword, newPassword, }: AuthChangePasswordRequest) { this.logger.info('ChangePassword'); return lastValueFrom( this.authService.AuthChangePassword({ accessToken, oldPassword, newPassword, }), ); } async resetPassword( { username }: AuthResetPasswordRequest, metadata: Metadata, ) { this.logger.info('resetPassword'); return lastValueFrom( this.authService.AuthResetPassword({ username }, metadata), ); } async verifyResetPasswordCode({ username, code, }: AuthVerifyResetPasswordCodeRequest) { this.logger.info('verifyResetPasswordCode'); return lastValueFrom( this.authService.AuthVerifyResetPasswordCode({ username, code }), ); } async confirmResetPassword( { username, code, newPassword }: AuthConfirmResetPasswordRequest, metadata: Metadata, ) { this.logger.info('confirmResetPassword'); return lastValueFrom( this.authService.AuthConfirmResetPassword( { username, code, newPassword, }, metadata, ), ); } async enableTotpMFA({ accessToken, password }: AuthEnableTotpMfaRequest) { this.logger.info('enableTotpMFA'); return lastValueFrom( this.authService.AuthEnableTotpMfa({ accessToken, password }), ); } async disableTotpMFA({ accessToken, password }: AuthDisableTotpMfaRequest) { this.logger.info('disableTotpMFA'); return lastValueFrom( this.authService.AuthDisableTotpMfa({ accessToken, password }), ); } async dismissTotpMFA({ accessToken }: AuthDismissTotpMfaRequest) { this.logger.info('dismissTotpMFA'); return lastValueFrom(this.authService.AuthDismissTotpMfa({ accessToken })); } async verifyTotp({ accessToken, totp }: AuthVerifyTotpMfaRequest) { this.logger.info('disableTotpMFA'); return lastValueFrom( this.authService.AuthVerifyTotpMfa({ accessToken, totp }), ); } async getSession(session: string) { return lastValueFrom(this.authService.AuthGetSession({ session })); } async oauthSignIn(data: { username: string; token: string }) { const { username, token } = data; return lastValueFrom( this.authService.AuthOauthSignIn({ token, username, refreshToken: '' }), ); } async blockUsers( users: string[], metadata: Metadata, ): Promise { this.logger.info('blockUsers - Service starting'); try { this.logger.debug('Calling BlockUser gRPC method', { metadata: { access_token: metadata.get('access_token'), language: metadata.get('language'), }, }); const response = await lastValueFrom( this.authService.BlockUser({ users }, metadata), ); this.logger.info('blockUsers - Service success', { response }); return response; } catch (error) { this.logger.error('blockUsers - Service error', { error: error.message, stack: error.stack, }); throw error; } } async unblockUsers( users: string[], metadata: Metadata, ): Promise { this.logger.info('unblockUsers'); return await lastValueFrom( this.authService.UnblockUser({ users }, metadata), ); } async resetUsers( users: string[], metadata: Metadata, ): Promise { this.logger.info('resetUsers'); try { this.logger.debug('Calling ResetUser gRPC method', { metadata: { access_token: metadata.get('access_token'), language: metadata.get('language'), }, }); const response = await lastValueFrom( this.authService.ResetUser({ users }, metadata), ); this.logger.info('resetUsers - Success', { response }); return response; } catch (error) { this.logger.error('resetUsers - Error', { error: error.message, stack: error.stack, }); throw error; } } }