import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common'; import { OracleDBService } from 'src/db/db.service'; import { InternalServerException } from 'src/exceptions/internalServerError.exception'; import * as oracledb from 'oracledb'; import { closeOracleDbConnection, fetchCursor, handleError } from 'src/utils/helper'; import { SPID_DTO, EMAIL_DTO, USERID_DTO, CreateClientLoginsDTO, CreateSPLoginsDTO, CreateUSCIBLoginsDTO, SPID_CLIENTID_DTO, SPID_EMAIL_DTO } from 'src/dto/property.dto'; import { BadRequestException } from 'src/exceptions/badRequest.exception'; import { AuthService } from 'src/auth/auth.service'; import { MailTypeDTO } from 'src/auth/auth.dto'; interface RoleDetail { [key: string]: any; } interface MenuDetail { [key: string]: any; } interface MenuPageDetail { [key: string]: any; } interface UserDetail { [key: string]: any; } export interface GetUserDetailsResult { roleDetails: RoleDetail[]; menuDetails: MenuDetail[]; menuPageDetails: MenuPageDetail[]; userDetails: UserDetail[]; } @Injectable() export class UserMaintenanceService { private readonly logger = new Logger(UserMaintenanceService.name); constructor( private readonly oracleDBService: OracleDBService, @Inject(forwardRef(() => AuthService)) private readonly authService: AuthService ) { } async GetSPUserDetails(body: USERID_DTO): Promise { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN SPCLIENTUSER_PKG.GetSPUserDetails( :P_USERID, :P_ROLECUR, :P_MENUCUR, :P_MENUPAGECUR, :P_USERDETAILS ); END;`, { P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, P_ROLECUR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }, P_MENUCUR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }, P_MENUPAGECUR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }, P_USERDETAILS: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }, }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); const outBinds = result.outBinds; if (!outBinds?.P_ROLECUR || !outBinds?.P_MENUCUR || !outBinds?.P_MENUPAGECUR || !outBinds?.P_USERDETAILS) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } let roleDetailsTemp: { "ROLENAME": "" }[] = await fetchCursor(outBinds.P_ROLECUR, UserMaintenanceService.name); let menuDetailsTemp: { "MENUNAME": "" }[] = await fetchCursor(outBinds.P_MENUCUR, UserMaintenanceService.name); let userdetailsTemp: any = await fetchCursor(outBinds.P_USERDETAILS, UserMaintenanceService.name); return { roleDetails: roleDetailsTemp.map(x => x.ROLENAME), menuDetails: menuDetailsTemp.map(x => x.MENUNAME), menuPageDetails: await fetchCursor(outBinds.P_MENUPAGECUR, UserMaintenanceService.name), userDetails: userdetailsTemp[0] }; } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } async LockUserAccount(body: SPID_EMAIL_DTO) { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN Userlogin_pkg.LockUserAccount( :P_SPID, :P_EMAILADDR, :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER }, P_EMAILADDR: { val: body.P_EMAILADDR, type: oracledb.DB_TYPE_NVARCHAR }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); await connection.commit(); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } return await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } // USCIB_LOGINS async GetUSCIBLogins() { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN Userlogin_pkg.GetUSCIBLogins( :P_CURSOR ); END;`, { P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } return await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } async CreateUSCIBLogins(body: CreateUSCIBLoginsDTO) { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN Userlogin_pkg.CreateUSCIBLogins( :P_USERID , :P_EMAILADDR , :P_LOOKUPCODE , :P_ENABLEPASSWORDPOLICY, :P_CURSOR ); END;`, { P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, P_EMAILADDR: { val: body.P_EMAILADDR, type: oracledb.DB_TYPE_NVARCHAR }, P_LOOKUPCODE: { val: body.P_LOOKUPCODE, type: oracledb.DB_TYPE_NVARCHAR }, P_ENABLEPASSWORDPOLICY: { val: body.P_ENABLEPASSWORDPOLICY, type: oracledb.DB_TYPE_NVARCHAR }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); await connection.commit(); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } const fres: any = await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); if (fres.length > 0 && fres[0].ERRORMESG) { this.logger.warn(fres[0].ERRORMESG); throw new BadRequestException(fres[0].ERRORMESG) } return { statusCode: 201, message: "Created successfully", ...fres[0] }; } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } // SP LOGINS async GetSPLogins(body: SPID_DTO) { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN Userlogin_pkg.GetSPLogins( :P_SPID , :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } return await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } async CreateSPLogins(body: CreateSPLoginsDTO) { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN Userlogin_pkg.CreateSPLogins( :P_SPID, :P_USERID, :P_DOMAIN, :P_EMAILADDR, :P_LOOKUPCODE, :P_ENABLEPASSWORDPOLICY, :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER }, P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, P_DOMAIN: { val: body.P_DOMAIN, type: oracledb.DB_TYPE_NVARCHAR }, P_EMAILADDR: { val: body.P_EMAILADDR, type: oracledb.DB_TYPE_NVARCHAR }, P_LOOKUPCODE: { val: body.P_LOOKUPCODE, type: oracledb.DB_TYPE_NVARCHAR }, P_ENABLEPASSWORDPOLICY: { val: body.P_ENABLEPASSWORDPOLICY, type: oracledb.DB_TYPE_NVARCHAR }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); await connection.commit(); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } const fres: any = await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); if (fres.length > 0 && fres[0].ERRORMESG) { this.logger.warn(fres[0].ERRORMESG); throw new BadRequestException(fres[0].ERRORMESG) } return { statusCode: 201, message: "Created successfully", ...fres[0] }; } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } // CLIENT LOGINS async GetClientloginsBySPID(body: SPID_DTO) { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN Userlogin_pkg.GetClientloginsBySPID( :P_SPID , :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } return await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } async GetClientloginsByClientID(body: SPID_CLIENTID_DTO) { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN Userlogin_pkg.GetClientloginsByClientID( :P_SPID, :p_clientid , :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER }, p_clientid: { val: body.P_CLIENTID, type: oracledb.DB_TYPE_NUMBER }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } return await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } async CreateClientLogins(body: CreateClientLoginsDTO) { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN Userlogin_pkg.CreateClientLogins( :P_SPID, :P_USERID, :P_CLIENTCONTACTID, :P_ENABLEPASSWORDPOLICY, :P_CURSOR ); END;`, { P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER }, P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR }, P_CLIENTCONTACTID: { val: body.P_CLIENTCONTACTID, type: oracledb.DB_TYPE_NUMBER }, P_ENABLEPASSWORDPOLICY: { val: body.P_ENABLEPASSWORDPOLICY, type: oracledb.DB_TYPE_NVARCHAR }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); await connection.commit(); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } const fres: any = await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); if (fres.length > 0 && fres[0].ERRORMESG) { this.logger.warn(fres[0].ERRORMESG); throw new BadRequestException(fres[0].ERRORMESG) } const mailRes = await this.authService.sendMail({ P_TO: body.P_USERID, P_MAIL_TYPE: MailTypeDTO.REGISTER_CLIENT }) if (mailRes.statusCode !== 200) { throw new InternalServerException(); } return { statusCode: 201, message: "Client registration initiated successfully", ...fres[0] }; } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } // validate email async ValidateEmail(body: EMAIL_DTO) { let connection; try { connection = await this.oracleDBService.getConnection(); const result = await connection.execute( `BEGIN userlogin_pkg.ValidateEmail( :P_EMAILADDR, :P_CURSOR ); END;`, { P_EMAILADDR: { val: body.P_EMAILADDR, type: oracledb.DB_TYPE_NVARCHAR }, P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } }, { outFormat: oracledb.OUT_FORMAT_OBJECT } ); const outBinds = result.outBinds; if (!outBinds?.P_CURSOR) { this.logger.error('One or more expected cursors are missing from stored procedure output.'); throw new InternalServerException("Incomplete data received from the database."); } return await fetchCursor(outBinds.P_CURSOR, UserMaintenanceService.name); } catch (error) { handleError(error, UserMaintenanceService.name) } finally { await closeOracleDbConnection(connection, UserMaintenanceService.name) } } }