Compare commits
19 Commits
8b964d2c84
...
966e039b87
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
966e039b87 | ||
|
|
1f49012644 | ||
|
|
d3c943d574 | ||
|
|
f4dd591198 | ||
|
|
d90c79fd67 | ||
|
|
0d4ac3e636 | ||
|
|
b553ff0623 | ||
|
|
cfb09b1f16 | ||
|
|
0cd9b8ca85 | ||
|
|
2259d306b1 | ||
|
|
d1d0c09042 | ||
|
|
c4f9f29208 | ||
|
|
49fe236b30 | ||
|
|
2eb3fe504b | ||
|
|
1f318d0039 | ||
|
|
b41e00959c | ||
|
|
1671eb9bdc | ||
|
|
600a1f7d75 | ||
|
|
7770642b80 |
2
api.http
2
api.http
@ -2,7 +2,7 @@ GET http://192.168.1.96:3006
|
||||
|
||||
###
|
||||
|
||||
GET http://localhost:3006
|
||||
GET http://localhost:3000/oracle/SearchHolder/1
|
||||
|
||||
###
|
||||
|
||||
|
||||
4498
package-lock.json
generated
4498
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -20,7 +20,6 @@
|
||||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs-modules/mailer": "^2.0.2",
|
||||
"@nestjs/common": "^11.0.1",
|
||||
"@nestjs/config": "^4.0.2",
|
||||
"@nestjs/core": "^11.0.1",
|
||||
@ -29,13 +28,16 @@
|
||||
"@nestjs/platform-express": "^11.0.1",
|
||||
"@nestjs/swagger": "^11.0.6",
|
||||
"@nestjs/typeorm": "^11.0.0",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"axios": "^1.10.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.1",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"handlebars": "^4.7.8",
|
||||
"joi": "^17.13.3",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
"jwk-to-pem": "^2.0.7",
|
||||
"mssql": "^10.0.4",
|
||||
"mssql": "^11.0.1",
|
||||
"mysql2": "^3.12.0",
|
||||
"nodemailer": "^7.0.3",
|
||||
"oracledb": "^6.7.2",
|
||||
@ -44,7 +46,8 @@
|
||||
"pg": "^8.13.3",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"typeorm": "^0.3.20"
|
||||
"typeorm": "^0.3.20",
|
||||
"uuid": "^11.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.2.0",
|
||||
@ -62,7 +65,8 @@
|
||||
"@types/node": "^22.10.7",
|
||||
"@types/oracledb": "^6.5.4",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"eslint": "^9.18.0",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"eslint": "^9.31.0",
|
||||
"eslint-config-prettier": "^10.0.1",
|
||||
"eslint-plugin-prettier": "^5.2.2",
|
||||
"globals": "^15.14.0",
|
||||
|
||||
14
public/mail-templates/a.hbs
Normal file
14
public/mail-templates/a.hbs
Normal file
@ -0,0 +1,14 @@
|
||||
<div style="font-family: Arial, sans-serif; padding: 20px; background-color: #f9f9f9;">
|
||||
<div style="max-width: 600px; margin: auto; background-color: #fff; padding: 30px; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
|
||||
<h2 style="color: #4A90E2;">🔐 Registration Initiated</h2>
|
||||
<p style="font-size: 16px;">A Registration has been successfully initiated for the email: <strong>{{to}}</strong></p>
|
||||
<p>Please click below to complete your registration:</p>
|
||||
<a href={{url}} style="display: inline-block; margin-top: 20px; background-color: #007BFF; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; font-size: 16px;">
|
||||
Register Now
|
||||
</a>
|
||||
<div style="margin-top: 40px;">
|
||||
<p style="color: #888;">Powered by</p>
|
||||
<img src="https://yourapp.com/logo.png" alt="App Logo" style="max-height: 50px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
14
public/mail-templates/b.hbs
Normal file
14
public/mail-templates/b.hbs
Normal file
@ -0,0 +1,14 @@
|
||||
<div style="font-family: Arial, sans-serif; padding: 20px; background-color: #f9f9f9;">
|
||||
<div style="max-width: 600px; margin: auto; background-color: #fff; padding: 30px; border-radius: 8px; text-align: center; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
|
||||
<h2 style="color: #4A90E2;">Reset your password</h2>
|
||||
{{!-- <p style="font-size: 16px;">A Registration has been successfully initiated for the email: <strong>{{to}}</strong></p> --}}
|
||||
<p>Please click below to complete your password reset:</p>
|
||||
<a href={{url}} style="display: inline-block; margin-top: 20px; background-color: #007BFF; color: white; padding: 12px 24px; text-decoration: none; border-radius: 4px; font-size: 16px;">
|
||||
Reset Now
|
||||
</a>
|
||||
<div style="margin-top: 40px;">
|
||||
<p style="color: #888;">Powered by</p>
|
||||
<img src="https://yourapp.com/logo.png" alt="App Logo" style="max-height: 50px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
1
public/mail-templates/demo.hbs
Normal file
1
public/mail-templates/demo.hbs
Normal file
@ -0,0 +1 @@
|
||||
<h1>Testing....</h1>
|
||||
@ -1,41 +1,39 @@
|
||||
import { Body, Controller, Get, HttpCode, Post, Put, Req, Res, UseInterceptors } from '@nestjs/common';
|
||||
import { Body, Controller, Get, HttpCode, Post, Put, Req, Res, UseGuards, UseInterceptors } from '@nestjs/common';
|
||||
import { AuthService } from './auth.service';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { AuthLoginDTO } from './auth.dto';
|
||||
import { AuthLoginDTO, SendMailDTO } from './auth.dto';
|
||||
import { Request, Response } from 'express';
|
||||
import { LogoutInterceptor } from 'src/interceptors/logout.interceptor';
|
||||
import { RegisterGuard } from 'src/guards/register.guard';
|
||||
import { RolesGuard } from 'src/guards/roles.guard';
|
||||
import { Roles } from 'src/decorators/roles.decorator';
|
||||
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||
|
||||
@ApiTags('Auth')
|
||||
@Controller()
|
||||
export class AuthController {
|
||||
constructor(private readonly authService: AuthService) { }
|
||||
|
||||
|
||||
// @Post('/login')
|
||||
// login(@Body() body: AuthLoginDTO) {
|
||||
// return this.authService.login(body);
|
||||
// }
|
||||
constructor(
|
||||
private readonly authService: AuthService,
|
||||
) { }
|
||||
|
||||
@Post('login')
|
||||
@HttpCode(200)
|
||||
async loginClient(@Body() body: AuthLoginDTO, @Res({ passthrough: true }) res: Response, @Req() req: Request) {
|
||||
let k: any = await this.authService.loginUser(body.P_EMAILADDR, body.P_PASSWORD, req);
|
||||
let k: any = await this.authService.loginUser(body.P_EMAILADDR.toLowerCase(), body.P_PASSWORD, req);
|
||||
|
||||
if (k.access_token) {
|
||||
res.cookie('access_token', k.access_token, {
|
||||
httpOnly: true,
|
||||
secure: true, // set to true if you're on HTTPS
|
||||
sameSite: 'none', // adjust based on your needs (strict, lax , none)
|
||||
maxAge: 90 * 1000, // convert seconds to ms if applicable
|
||||
secure: true,
|
||||
sameSite: 'none'
|
||||
});
|
||||
}
|
||||
|
||||
if (k.refresh_token) {
|
||||
res.cookie('refresh_token', k.refresh_token, {
|
||||
httpOnly: true,
|
||||
secure: true, // set to true if you're on HTTPS
|
||||
sameSite: 'none', // adjust based on your needs (strict, lax , none)
|
||||
maxAge: 90 * 1000, // convert seconds to ms if applicable
|
||||
secure: true,
|
||||
sameSite: 'none'
|
||||
});
|
||||
}
|
||||
|
||||
@ -44,8 +42,8 @@ export class AuthController {
|
||||
|
||||
// @UseGuards(RegisterGuard)
|
||||
@Post('register')
|
||||
async register(@Body() body: AuthLoginDTO, @Req() req: Request) {
|
||||
return this.authService.registerUser(body, req);
|
||||
async register(@Body() body: AuthLoginDTO) {
|
||||
return this.authService.registerUser(body);
|
||||
}
|
||||
|
||||
@UseInterceptors(LogoutInterceptor)
|
||||
@ -55,15 +53,24 @@ export class AuthController {
|
||||
const refreshToken = req.user?.refreshToken;
|
||||
let rst: any = await this.authService.logoutUser(refreshToken);
|
||||
if (rst.statusCode === 200) {
|
||||
res.clearCookie('access_token');
|
||||
res.clearCookie('refresh_token');
|
||||
res.clearCookie('access_token', {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: 'none'
|
||||
});
|
||||
res.clearCookie('refresh_token', {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: 'none'
|
||||
});
|
||||
}
|
||||
res.json({ ...rst })
|
||||
}
|
||||
|
||||
@UseGuards(RegisterGuard)
|
||||
@Put('forgot-password')
|
||||
async forgotPassword() {
|
||||
return this.authService.forgotPassword();
|
||||
async forgotPassword(@Body() body: AuthLoginDTO, @Req() req: Request) {
|
||||
return this.authService.forgotPassword(body, req);
|
||||
}
|
||||
|
||||
@Get('refresh-tokens')
|
||||
@ -73,9 +80,9 @@ export class AuthController {
|
||||
if (k.access_token) {
|
||||
res.cookie('access_token', k.access_token, {
|
||||
httpOnly: true,
|
||||
secure: true, // set to true if you're on HTTPS
|
||||
sameSite: 'none', // adjust based on your needs (strict, lax , none)
|
||||
maxAge: 90 * 1000, // convert seconds to ms if applicable
|
||||
secure: true,
|
||||
sameSite: 'none',
|
||||
maxAge: 8 * 60 * 60 * 1000,
|
||||
path: '/'
|
||||
});
|
||||
}
|
||||
@ -83,9 +90,9 @@ export class AuthController {
|
||||
if (k.refresh_token) {
|
||||
res.cookie('refresh_token', k.refresh_token, {
|
||||
httpOnly: true,
|
||||
secure: true, // set to true if you're on HTTPS
|
||||
sameSite: 'none', // adjust based on your needs (strict, lax , none)
|
||||
maxAge: 90 * 1000, // convert seconds to ms if applicable
|
||||
secure: true,
|
||||
sameSite: 'none',
|
||||
maxAge: 8 * 60 * 60 * 1000,
|
||||
path: '/'
|
||||
});
|
||||
}
|
||||
@ -93,6 +100,15 @@ export class AuthController {
|
||||
return { statusCode: 200, message: "Tokens refreshed successfully" }
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard, RolesGuard)
|
||||
@Roles('sa')
|
||||
@Post('sendmail')
|
||||
@HttpCode(200)
|
||||
async sendMail(@Body() body: SendMailDTO) {
|
||||
// let token = await this.jwtService.generateToken({ email: mail })
|
||||
return this.authService.sendMail(body);
|
||||
}
|
||||
|
||||
// @Get('checkRoles')
|
||||
// @UseGuards(JwtAuthGuard, RolesGuard)
|
||||
// @Roles('ca')
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString } from 'class-validator';
|
||||
import { Transform, Type } from 'class-transformer';
|
||||
import { IsEmail, IsEnum, IsObject, IsOptional, IsString, ValidateNested } from 'class-validator';
|
||||
|
||||
export class AuthLoginDTO {
|
||||
@ApiProperty({ required: true })
|
||||
@ -9,4 +10,52 @@ export class AuthLoginDTO {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
P_PASSWORD: string;
|
||||
}
|
||||
|
||||
export enum MailTypeDTO {
|
||||
REGISTER_CLIENT = "REGISTER_CLIENT",
|
||||
REGISTER_SP = "REGISTER_SP",
|
||||
REGISTER_USCIB = "REGISTER_USCIB",
|
||||
FORGOT_PASSWORD = "FORGOT_PASSWORD"
|
||||
// DEMO_MAIL = "DEMO_MAIL"
|
||||
}
|
||||
|
||||
export class SendMailDTO {
|
||||
@ApiProperty({ required: true, example: 'user@example.com' })
|
||||
@IsEmail({}, { message: 'P_TO must be a valid email address' })
|
||||
P_TO: string;
|
||||
|
||||
@ApiProperty({ enum: MailTypeDTO, required: true })
|
||||
@Transform(({ value }) => value?.toUpperCase())
|
||||
@IsEnum(MailTypeDTO, { message: "Invalid P_MAIL_TYPE" })
|
||||
P_MAIL_TYPE: MailTypeDTO;
|
||||
}
|
||||
|
||||
export class MailContextDTO {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
to: string;
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
url: string;
|
||||
|
||||
}
|
||||
|
||||
export class MailTemplateDTO {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
to: string;
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
subject: string;
|
||||
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
templateName: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
variables?: Record<string, any>;
|
||||
}
|
||||
@ -1,11 +1,60 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { forwardRef, Module } from '@nestjs/common';
|
||||
import { AuthService } from './auth.service';
|
||||
import { AuthController } from './auth.controller';
|
||||
import { DbModule } from 'src/db/db.module';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { OracleModule } from 'src/oracle/oracle.module';
|
||||
import { MailModule } from 'src/mail/mail.module';
|
||||
|
||||
@Module({
|
||||
imports: [DbModule],
|
||||
providers: [AuthService],
|
||||
imports: [DbModule,MailModule, forwardRef(() => OracleModule)],
|
||||
providers: [
|
||||
AuthService,
|
||||
{
|
||||
provide: "REGISTER_SIGN_JWT",
|
||||
useFactory: (config: ConfigService) => {
|
||||
const base64Key = config.get<string>('JWT_REGISTER_PRIVATE_KEY');
|
||||
if (!base64Key) {
|
||||
throw new Error('JWT_REGISTER_PRIVATE_KEY is not defined in the config');
|
||||
}
|
||||
const secretKey = Buffer.from(base64Key, 'base64').toString('utf-8');
|
||||
|
||||
const expiry = config.get<string>('JWT_REGISTER_EXPIRY');
|
||||
|
||||
if (!expiry) {
|
||||
throw new Error('JWT_REGISTER_PRIVATE_KEY is not defined in the config');
|
||||
}
|
||||
|
||||
return new JwtService({
|
||||
secret: secretKey,
|
||||
signOptions: {
|
||||
expiresIn: expiry,
|
||||
algorithm: 'ES384'
|
||||
},
|
||||
})
|
||||
},
|
||||
inject: [ConfigService],
|
||||
},
|
||||
{
|
||||
provide: "REGISTER_VERIFY_JWT",
|
||||
useFactory: (config: ConfigService) => {
|
||||
const base64Key = config.get<string>('JWT_REGISTER_PUBLIC_KEY');
|
||||
if (!base64Key) {
|
||||
throw new Error('JWT_REGISTER_PRIVATE_KEY is not defined in the config');
|
||||
}
|
||||
const secretKey = Buffer.from(base64Key, 'base64').toString('utf-8');
|
||||
|
||||
return new JwtService({
|
||||
secret: secretKey,
|
||||
verifyOptions: {
|
||||
algorithms: ['ES384']
|
||||
}
|
||||
})
|
||||
},
|
||||
inject: [ConfigService],
|
||||
}
|
||||
],
|
||||
controllers: [AuthController],
|
||||
exports: [AuthService]
|
||||
})
|
||||
|
||||
@ -1,15 +1,29 @@
|
||||
import { Injectable, InternalServerErrorException } from '@nestjs/common';
|
||||
import { Inject, Injectable, InternalServerErrorException } from '@nestjs/common';
|
||||
import { OracleDBService } from 'src/db/db.service';
|
||||
import { AuthLoginDTO } from './auth.dto';
|
||||
import { AuthLoginDTO, MailTemplateDTO, MailTypeDTO, SendMailDTO } from './auth.dto';
|
||||
import * as oracledb from 'oracledb';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
import axios, { AxiosError, AxiosRequestConfig } from 'axios';
|
||||
import { Request } from 'express';
|
||||
import * as jwkToPem from "jwk-to-pem"
|
||||
import * as jwt from "jsonwebtoken"
|
||||
import { UnauthorizedException } from 'src/exceptions/unauthorized.exception';
|
||||
import { ConflictException } from 'src/exceptions/conflict.exception';
|
||||
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { UserMaintenanceService } from 'src/oracle/user-maintenance/user-maintenance.service';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { MailService } from 'src/mail/mail.service';
|
||||
|
||||
|
||||
interface DecodedToken {
|
||||
email: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface IntrospectResult {
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
@ -25,10 +39,16 @@ export class AuthService {
|
||||
private readonly TOKEN_URL: string;
|
||||
private readonly USERS_URL: string;
|
||||
|
||||
|
||||
constructor(
|
||||
private readonly oracleDBService: OracleDBService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly mailService: MailService,
|
||||
private readonly userMaintenanceService: UserMaintenanceService,
|
||||
@Inject("REGISTER_SIGN_JWT") readonly REGISTER_SIGN_JWT: JwtService,
|
||||
@Inject("REGISTER_VERIFY_JWT") readonly REGISTER_VERIFY_JWT: JwtService
|
||||
) {
|
||||
|
||||
const KEYCLOAK_URL = this.configService.get<string>('KEYCLOAK_URL');
|
||||
if (!KEYCLOAK_URL) throw new Error('Environment variable KEYCLOAK_URL is not set');
|
||||
this.KEYCLOAK_URL = KEYCLOAK_URL;
|
||||
@ -53,7 +73,8 @@ export class AuthService {
|
||||
|
||||
this.TOKEN_URL = `${this.KEYCLOAK_BASE_URL}/token`
|
||||
|
||||
this.USERS_URL = `${this.KEYCLOAK_URL}/realms/${this.KEYCLOAK_REALM}/users`;
|
||||
this.USERS_URL = `${this.KEYCLOAK_URL}/admin/realms/${this.KEYCLOAK_REALM}/users`;
|
||||
|
||||
}
|
||||
|
||||
async login(body: AuthLoginDTO) {
|
||||
@ -121,75 +142,120 @@ export class AuthService {
|
||||
}
|
||||
|
||||
private async getPublicKey(kid: string): Promise<string> {
|
||||
if (this.keyCache[kid]) return this.keyCache[kid];
|
||||
const { data } = await axios.get(this.JWKS_URL);
|
||||
const key = data.keys.find((k) => k.kid === kid);
|
||||
if (!key) throw new InternalServerErrorException('Key not found');
|
||||
const pem = jwkToPem(key);
|
||||
this.keyCache[kid] = pem;
|
||||
return pem;
|
||||
try {
|
||||
// Check if the key is already cached
|
||||
if (this.keyCache[kid]) return this.keyCache[kid];
|
||||
|
||||
// Fetch the JWKS (JSON Web Key Set)
|
||||
const { data } = await axios.get(this.JWKS_URL);
|
||||
|
||||
// Validate the response shape
|
||||
if (!data?.keys || !Array.isArray(data.keys)) {
|
||||
console.log("Invalid JWKS response");
|
||||
throw new UnauthorizedException('Authentication failed');
|
||||
}
|
||||
|
||||
// Find the key with the matching kid
|
||||
const key = data.keys.find((k) => k.kid === kid);
|
||||
if (!key) {
|
||||
console.log("Authentication failed: Key not found");
|
||||
throw new UnauthorizedException('Authentication failed');
|
||||
}
|
||||
|
||||
// Convert JWK to PEM format and cache it
|
||||
const pem = jwkToPem(key);
|
||||
this.keyCache[kid] = pem;
|
||||
|
||||
return pem;
|
||||
} catch (error) {
|
||||
if (error instanceof UnauthorizedException) {
|
||||
throw error; // Let UnauthorizedException bubble up as-is
|
||||
}
|
||||
// Optionally log error details for debugging
|
||||
console.error('Failed to retrieve or process JWKS:', error);
|
||||
// Wrap other errors as InternalServerException
|
||||
console.log('Failed to retrieve public key');
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
async introspectToken(token: string): Promise<any> {
|
||||
async introspectToken(token: string): Promise<IntrospectResult> {
|
||||
try {
|
||||
const decoded = jwt.decode(token) as DecodedToken;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append('token', token);
|
||||
params.append('client_id', this.CLIENT_ID);
|
||||
params.append('client_secret', this.CLIENT_SECRET);
|
||||
const { email } = decoded;
|
||||
|
||||
if (!email) throw new UnauthorizedException('Authentication failed');
|
||||
|
||||
const response = await axios.post(this.TOKENS_INTROSPECT_URL, params, {
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
});
|
||||
const sessionData = await this.getUserSession(email);
|
||||
|
||||
return response.data;
|
||||
return { active: Array.isArray(sessionData) && sessionData.length > 0 };
|
||||
|
||||
} catch (error: any) {
|
||||
console.log("Error in introspectToken:", error.message || error);
|
||||
|
||||
if (error instanceof UnauthorizedException) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new InternalServerErrorException('Failed to introspect token');
|
||||
}
|
||||
}
|
||||
|
||||
async getUserSession(email: string) {
|
||||
try {
|
||||
const uid = await this.getUserIdByEmail(email);
|
||||
|
||||
if (!uid) throw new UnauthorizedException('No user ID found for email.');
|
||||
|
||||
const userInfoUrl = `${this.USERS_URL}/${uid}/sessions`;
|
||||
|
||||
const adminToken = await this.getAdminAccessToken();
|
||||
|
||||
const response = await axios.get(userInfoUrl, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${adminToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
const sessionData = response.data;
|
||||
|
||||
return sessionData
|
||||
|
||||
} catch (error) {
|
||||
if (error instanceof UnauthorizedException) throw error
|
||||
console.log("Error while getting User session.....");
|
||||
throw new InternalServerErrorException()
|
||||
}
|
||||
}
|
||||
|
||||
async decodeToken(token: string): Promise<any> {
|
||||
const decodedHeader = jwt.decode(token, { complete: true });
|
||||
|
||||
if (!decodedHeader || typeof decodedHeader !== 'object') {
|
||||
throw new Error('Invalid token format');
|
||||
throw new UnauthorizedException("Authentication failed")
|
||||
}
|
||||
|
||||
const kid: any = decodedHeader.header.kid;
|
||||
|
||||
const publicKey = await this.getPublicKey(kid);
|
||||
|
||||
const introspection = await this.introspectToken(token);
|
||||
|
||||
console.log("introspection : ", introspection.active, " : so Unauthorized!");
|
||||
|
||||
if (!introspection.active) {
|
||||
throw new Error('Unauthorized');
|
||||
console.log("Introspect failed for token");
|
||||
throw new UnauthorizedException("Authentication Failed")
|
||||
}
|
||||
|
||||
const verified = jwt.verify(token, publicKey, { algorithms: ['RS256'] });
|
||||
return verified;
|
||||
}
|
||||
|
||||
async getAdminAccessTokenx(): Promise<string> {
|
||||
const data = new URLSearchParams();
|
||||
data.append('grant_type', 'client_credentials');
|
||||
data.append('client_id', this.CLIENT_ID);
|
||||
data.append('client_secret', this.CLIENT_SECRET);
|
||||
try {
|
||||
const response: AxiosResponse = await axios.post(this.KEYCLOAK_URL, data, {
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
});
|
||||
return response.data.access_token;
|
||||
} catch (error) {
|
||||
console.error('Error getting Keycloak access token:', error.response ? error.response.data : error.message);
|
||||
throw new Error('Failed to obtain Keycloak access token');
|
||||
}
|
||||
return verified;
|
||||
}
|
||||
|
||||
async loginUser(username: string, password: string, req: Request): Promise<any> {
|
||||
|
||||
const accessToken = req.cookies['access_token'];
|
||||
const refreshToken = req.cookies['refresh_token'];
|
||||
|
||||
// if (!accessToken && !refreshToken) {
|
||||
const access_token = req.cookies?.access_token;
|
||||
const refresh_token = req.cookies?.refresh_token;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append('grant_type', 'password');
|
||||
@ -199,90 +265,204 @@ export class AuthService {
|
||||
params.append('password', password);
|
||||
|
||||
try {
|
||||
const userSession = await this.getUserSession(username)
|
||||
|
||||
if (access_token && refresh_token && userSession.length > 0) {
|
||||
|
||||
const getSub: any = jwt.decode(refresh_token, { complete: true })
|
||||
|
||||
const user: any = await this.getUserDetailsById(getSub?.payload.sub)
|
||||
|
||||
if (user.email !== username) {
|
||||
throw new UnauthorizedException("Authentication failed")
|
||||
}
|
||||
|
||||
let tokens = await this.getTokenFromRefreshToken(req);
|
||||
const decoded = jwt.decode(access_token, { complete: true });
|
||||
const email: any = (decoded && typeof decoded === 'object') ? (decoded as any).payload?.email : undefined;
|
||||
return { ...tokens, email }
|
||||
|
||||
}
|
||||
|
||||
const response = await axios.post(this.TOKEN_URL, params, {
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
});
|
||||
console.log('first time data ...');
|
||||
|
||||
let k = { ...response.data, email: username };
|
||||
|
||||
return k;
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
console.log("error while logging : ", error.message);
|
||||
|
||||
throw new BadRequestException('Invalid username or password');
|
||||
}
|
||||
// }
|
||||
|
||||
// else if (accessToken && refreshToken) {
|
||||
// return { access_token: accessToken, refresh_token: refreshToken, email: username }
|
||||
// }
|
||||
}
|
||||
|
||||
async getUserIdByEmail(email: string) {
|
||||
|
||||
let url = `${this.USERS_URL}?email=${email}`;
|
||||
|
||||
let adminAccessToken = await this.getAdminAccessToken();
|
||||
|
||||
const options: AxiosRequestConfig = {
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${adminAccessToken}`,
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
};
|
||||
|
||||
async getUserIdByEmail(email: string): Promise<string> {
|
||||
try {
|
||||
const { data } = await axios.request(options);
|
||||
return data[0]?.id;
|
||||
const adminAccessToken = await this.getAdminAccessToken();
|
||||
const url = `${this.USERS_URL}?email=${encodeURIComponent(email)}`;
|
||||
const options: AxiosRequestConfig = {
|
||||
method: 'GET',
|
||||
url,
|
||||
headers: {
|
||||
Authorization: `Bearer ${adminAccessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
|
||||
const response = await axios.request(options);
|
||||
|
||||
if (response.status !== 200 || !Array.isArray(response.data)) {
|
||||
console.log("failed to retrieve user-id....");
|
||||
throw new UnauthorizedException("Authentication failed")
|
||||
}
|
||||
|
||||
const user = response.data[0];
|
||||
if (user?.id) {
|
||||
return user.id
|
||||
} else {
|
||||
throw new UnauthorizedException("Authentication failed")
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
// console.error(error);
|
||||
console.log(error.message);
|
||||
console.log("Error in getUserIdByEmail ...........");
|
||||
if (error instanceof UnauthorizedException) {
|
||||
throw error
|
||||
}
|
||||
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
async forgotPassword() {
|
||||
async getUserDetailsById(id: string) {
|
||||
try {
|
||||
const adminAccessToken = await this.getAdminAccessToken();
|
||||
|
||||
const validatePasswordURLSearchParams = new URLSearchParams({
|
||||
grant_type: 'password',
|
||||
client_id: `${this.CLIENT_ID}`,
|
||||
client_secret: `${this.CLIENT_SECRET}`,
|
||||
username: `${'a@gmail.com'}`,
|
||||
password: `${'A1!bcdef'}`,
|
||||
});
|
||||
const userResponse = await axios.get(`${this.USERS_URL}/${id}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${adminAccessToken}`
|
||||
},
|
||||
});
|
||||
|
||||
let userID = await this.getUserIdByEmail("");
|
||||
if (userResponse.status !== 200 || !Array.isArray(userResponse.data)) {
|
||||
|
||||
let resetPasswordURL = `${this.USERS_URL}/${userID}/reset-password`;
|
||||
throw new UnauthorizedException("Authentication failed");
|
||||
}
|
||||
|
||||
return userResponse.data;
|
||||
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
|
||||
console.log("Error in getUserDetailsById ...........");
|
||||
if (error instanceof UnauthorizedException) {
|
||||
throw error;
|
||||
}
|
||||
else if (error instanceof BadRequestException) {
|
||||
throw error;
|
||||
}
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
async getUserDetailsByEmail(email: string): Promise<any> {
|
||||
try {
|
||||
const adminAccessToken = await this.getAdminAccessToken();
|
||||
|
||||
const userResponse = await axios.get(`${this.USERS_URL}?email=${encodeURIComponent(email)}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${adminAccessToken}`
|
||||
},
|
||||
});
|
||||
|
||||
if (userResponse.status !== 200 || !Array.isArray(userResponse.data)) {
|
||||
console.log("userResponse : ", userResponse);
|
||||
console.log("userResponse status : ", userResponse.status);
|
||||
|
||||
throw new UnauthorizedException("Authentication failed");
|
||||
}
|
||||
|
||||
const user = userResponse.data[0];
|
||||
|
||||
if (userResponse.data.length === 0 || !user?.id) {
|
||||
throw new BadRequestException("Invalid User");
|
||||
}
|
||||
const roleUrl = `${this.USERS_URL}/${user.id}/role-mappings`;
|
||||
|
||||
const roleResponse = await axios.get(roleUrl, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${adminAccessToken}`
|
||||
},
|
||||
});
|
||||
|
||||
const clientRoles = roleResponse.data;
|
||||
|
||||
return {
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
forgotPassword: user.attributes?.["forgot-password"][0] || null,
|
||||
role: clientRoles.clientMappings?.[this.CLIENT_ID]?.mappings?.map((x) => x.name) || []
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
|
||||
console.log("Error in getUserDetailsByEmail ...........");
|
||||
if (error instanceof UnauthorizedException) {
|
||||
throw error;
|
||||
}
|
||||
else if (error instanceof BadRequestException) {
|
||||
throw error;
|
||||
}
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async forgotPassword(body: AuthLoginDTO, req: Request) {
|
||||
|
||||
let det = await req['user'];
|
||||
if (det?.email !== body.P_EMAILADDR) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
const userDetails = await this.getUserDetailsByEmail(body.P_EMAILADDR);
|
||||
|
||||
if (userDetails.forgotPassword !== det.rstID) {
|
||||
throw new UnauthorizedException("Token verification failed");
|
||||
}
|
||||
|
||||
let adminAccessToken = await this.getAdminAccessToken();
|
||||
|
||||
const options1: AxiosRequestConfig = {
|
||||
// console.log(`${this.USERS_URL}/${userDetails.id}/reset-password`);
|
||||
|
||||
|
||||
const options2: AxiosRequestConfig = {
|
||||
method: 'PUT',
|
||||
url: resetPasswordURL,
|
||||
url: `${this.USERS_URL}/${userDetails.id}/reset-password`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${adminAccessToken}`
|
||||
Authorization: `Bearer ${adminAccessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
type: 'password',
|
||||
value: 'A1!bcdef',
|
||||
value: body.P_PASSWORD,
|
||||
temporary: false,
|
||||
}
|
||||
};
|
||||
|
||||
const options2: AxiosRequestConfig = {
|
||||
method: 'POST',
|
||||
url: this.TOKEN_URL,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
data: validatePasswordURLSearchParams
|
||||
};
|
||||
|
||||
try {
|
||||
const { data } = await axios.request(options2);
|
||||
|
||||
console.log("forgot password status API request", data.status);
|
||||
|
||||
const forgotPasswordStatus = await this.updateForgotPassword(userDetails)
|
||||
|
||||
if (!forgotPasswordStatus) {
|
||||
throw new InternalServerErrorException("Update forgot-password failed")
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: 'password reset successfull' }
|
||||
} catch (error) {
|
||||
// console.error(error);
|
||||
@ -295,39 +475,53 @@ export class AuthService {
|
||||
|
||||
async getAdminAccessToken() {
|
||||
try {
|
||||
const adminParams = new URLSearchParams();
|
||||
adminParams.append('grant_type', 'client_credentials');
|
||||
adminParams.append('client_id', this.CLIENT_ID);
|
||||
adminParams.append('client_secret', this.CLIENT_SECRET);
|
||||
const adminParams = new URLSearchParams({
|
||||
grant_type: 'client_credentials',
|
||||
client_id: this.CLIENT_ID,
|
||||
client_secret: this.CLIENT_SECRET,
|
||||
});
|
||||
|
||||
const adminTokenResponse = await axios.post(this.TOKEN_URL,
|
||||
adminParams,
|
||||
{
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
});
|
||||
console.log(adminTokenResponse.data);
|
||||
const { data } = await axios.post(this.TOKEN_URL, adminParams, {
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
timeout: 6000, // optional: add a timeout to avoid hanging requests
|
||||
});
|
||||
|
||||
const adminAccessToken = adminTokenResponse.data.access_token;
|
||||
if (!data.access_token) {
|
||||
console.log("failed to retrieve admin access token.....");
|
||||
throw new UnauthorizedException("Authentication failed")
|
||||
}
|
||||
|
||||
return data.access_token;
|
||||
|
||||
return adminAccessToken;
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
throw error
|
||||
if (error instanceof UnauthorizedException) throw error
|
||||
console.log("Error in getAdminAccessToken");
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
async registerUser(body: AuthLoginDTO, req: Request) {
|
||||
let det = await req['user'];
|
||||
if (det?.email !== body.P_EMAILADDR) {
|
||||
async registerUser(body: AuthLoginDTO) {
|
||||
// let det = await req['user'];
|
||||
// if (det?.email !== body.P_EMAILADDR) {
|
||||
// throw new BadRequestException();
|
||||
// }
|
||||
|
||||
const emailVerifyResponse: any = await this.userMaintenanceService.ValidateEmail({ P_EMAILADDR: body.P_EMAILADDR })
|
||||
|
||||
if (Array.isArray(emailVerifyResponse) && emailVerifyResponse[0].ERRORMESG) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
const userPayload = {
|
||||
username: body.P_EMAILADDR,
|
||||
username: body.P_EMAILADDR.toLowerCase(),
|
||||
// firstName:"A",
|
||||
// lastName:"B",
|
||||
email: body.P_EMAILADDR,
|
||||
email: body.P_EMAILADDR.toLowerCase(),
|
||||
emailVerified: true,
|
||||
enabled: true,
|
||||
attributes: {
|
||||
"forgot-password": ["none"]
|
||||
},
|
||||
credentials: [
|
||||
{
|
||||
type: 'password',
|
||||
@ -337,7 +531,7 @@ export class AuthService {
|
||||
],
|
||||
};
|
||||
|
||||
console.log(userPayload);
|
||||
// console.log(userPayload);
|
||||
|
||||
const adminAccessToken = await this.getAdminAccessToken();
|
||||
|
||||
@ -351,27 +545,96 @@ export class AuthService {
|
||||
|
||||
if (response.status === 201) {
|
||||
|
||||
// console.log("Assigning role : ");
|
||||
|
||||
// console.log("checking validate email response : ", response);
|
||||
|
||||
|
||||
const uid = await this.getUserIdByEmail(body.P_EMAILADDR);
|
||||
|
||||
const res = await this.assignRoleToUser(uid, "ca");
|
||||
let ROLE = "";
|
||||
|
||||
|
||||
if (Array.isArray(emailVerifyResponse) && !emailVerifyResponse[0].ERRORMESG) {
|
||||
switch (emailVerifyResponse[0].SOURCE) {
|
||||
case "USCIB": ROLE = 'ua'; break;
|
||||
case "SP": ROLE = 'sa'; break;
|
||||
case "CLIENT": ROLE = 'ca'; break;
|
||||
}
|
||||
}
|
||||
|
||||
// console.log("Role to assign : ", ROLE);
|
||||
|
||||
|
||||
if (!ROLE) {
|
||||
console.log("ERROR while giving access : ");
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
|
||||
const res = await this.assignRoleToUser(uid, ROLE);
|
||||
|
||||
console.log("Assigning Role sussessfully ");
|
||||
|
||||
console.log(res);
|
||||
|
||||
return { message: 'User created successfully' };
|
||||
return { statusCode: 201, message: 'User registered successfully' };
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
// handle errors like user exists, validation errors, etc.
|
||||
console.log(error.message);
|
||||
|
||||
if (error.message === "Request failed with status code 409") {
|
||||
throw new ConflictException("User already exist");
|
||||
}
|
||||
|
||||
else if (error instanceof BadRequestException) {
|
||||
console.log("ERROR while registering : ", error.message);
|
||||
return error;
|
||||
}
|
||||
console.log("ERROR while giving access : ", error.message);
|
||||
throw new InternalServerErrorException('Failed to create user');
|
||||
}
|
||||
}
|
||||
|
||||
async assignRoleToUser(userId: string, roleName: string): Promise<{ message: string }> {
|
||||
try {
|
||||
const token = await this.getAdminAccessToken();
|
||||
const clientId = await this.getClientUUID();
|
||||
const role = await this.getClientRole(roleName);
|
||||
|
||||
const url = `${this.KEYCLOAK_URL}/admin/realms/${this.KEYCLOAK_REALM}/users/${userId}/role-mappings/clients/${clientId}`;
|
||||
|
||||
const response = await axios.post(url, [role], {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
validateStatus: () => true, // Let us handle non-2xx statuses manually
|
||||
});
|
||||
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
console.log(`✅ Role "${roleName}" successfully assigned to user ${userId}.`);
|
||||
return { message: "Successfully assigned to user" };
|
||||
} else {
|
||||
console.error(`❌ Failed to assign role. Status: ${response.status}, Data:`, response.data);
|
||||
throw new Error(`Failed to assign role "${roleName}" to user ${userId}. Status: ${response.status}`);
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle Axios errors more gracefully
|
||||
if (axios.isAxiosError(error)) {
|
||||
const axiosError = error as AxiosError;
|
||||
console.error(`🔥 Axios error: ${axiosError.message}`);
|
||||
if (axiosError.response) {
|
||||
console.error(`Response status: ${axiosError.response.status}`);
|
||||
console.error(`Response data:`, axiosError.response.data);
|
||||
}
|
||||
} else {
|
||||
console.error(`🔥 Unexpected error:`, error);
|
||||
}
|
||||
|
||||
throw new Error(`Error assigning role "${roleName}" to user ${userId}. See logs for details.`);
|
||||
}
|
||||
}
|
||||
|
||||
async logoutUser(refreshToken: string): Promise<any> {
|
||||
const url = `${this.KEYCLOAK_BASE_URL}/logout`;
|
||||
|
||||
@ -454,45 +717,18 @@ export class AuthService {
|
||||
}
|
||||
}
|
||||
|
||||
async assignRoleToUser(userId: string, roleName: string): Promise<any> {
|
||||
try {
|
||||
const token = await this.getAdminAccessToken();
|
||||
|
||||
const clientId = await this.getClientUUID();
|
||||
|
||||
const role = await this.getClientRole(roleName);
|
||||
|
||||
const url = `${this.KEYCLOAK_URL}/admin/realms/${this.KEYCLOAK_REALM}/users/${userId}/role-mappings/clients/${clientId}`;
|
||||
|
||||
const response = await axios.post(
|
||||
url,
|
||||
[role],
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
validateStatus: () => true, // To manually check status if needed
|
||||
}
|
||||
);
|
||||
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
console.log(`✅ Role "${roleName}" successfully assigned to user ${userId}.`);
|
||||
|
||||
return { message: "Successfully assigned to user" }
|
||||
} else {
|
||||
throw new Error(`❌ Failed to assign role. Status: ${response.status}. Data: ${JSON.stringify(response.data)}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`🔥 Error assigning role "${roleName}" to user ${userId}:`, error.message || error);
|
||||
throw error; // Rethrow to allow upstream handling
|
||||
}
|
||||
}
|
||||
|
||||
async getTokenFromRefreshToken(req: Request) {
|
||||
|
||||
const refreshToken = req.cookies['refresh_token'];
|
||||
|
||||
if (!refreshToken) {
|
||||
|
||||
console.log("refesh token not present");
|
||||
|
||||
throw new UnauthorizedException('Authentication failed');
|
||||
|
||||
}
|
||||
|
||||
const params = new URLSearchParams();
|
||||
@ -501,6 +737,8 @@ export class AuthService {
|
||||
params.append('client_secret', this.CLIENT_SECRET);
|
||||
params.append('refresh_token', refreshToken);
|
||||
|
||||
// console.log("url for refresh is : ", `${this.KEYCLOAK_URL}/auth/realms/${this.KEYCLOAK_REALM}/protocol/openid-connect/token`);
|
||||
|
||||
try {
|
||||
const response = await axios.post(this.TOKEN_URL, params, {
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
@ -508,8 +746,184 @@ export class AuthService {
|
||||
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.log(error.message);
|
||||
if (axios.isAxiosError(error) && error.response) {
|
||||
console.error('🔴 Axios error:', {
|
||||
status: error.response.status,
|
||||
data: error.response.data,
|
||||
});
|
||||
} else {
|
||||
console.error('🔴 Unexpected error:', error.message);
|
||||
}
|
||||
console.log("Error while refreshing tokens : ", error.message);
|
||||
throw new UnauthorizedException('Authentication failed');
|
||||
}
|
||||
}
|
||||
|
||||
async generateUUID() {
|
||||
try {
|
||||
const uuid = uuidv4();
|
||||
|
||||
if (!uuid || typeof uuid !== 'string') {
|
||||
throw new InternalServerErrorException('Invalid UUID generated');
|
||||
}
|
||||
|
||||
return uuid;
|
||||
} catch (error) {
|
||||
console.error('UUID generation failed:', error.message);
|
||||
throw new InternalServerErrorException('Failed to generate unique ID');
|
||||
}
|
||||
}
|
||||
|
||||
async generateToken(payload: { P_TO: string, uuid?: string }) {
|
||||
let token: string;
|
||||
try {
|
||||
if (payload.uuid) {
|
||||
token = this.REGISTER_SIGN_JWT.sign({ email: payload.P_TO, rstID: payload.uuid });
|
||||
}
|
||||
else {
|
||||
token = this.REGISTER_SIGN_JWT.sign({ email: payload.P_TO });
|
||||
}
|
||||
console.log("Register token : ", token);
|
||||
|
||||
if (!token) {
|
||||
console.log("Register Token Generation failed");
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error.message);
|
||||
|
||||
throw new InternalServerErrorException("Register Token Generation failed")
|
||||
}
|
||||
}
|
||||
|
||||
async updateForgotPassword(user: any, rstID?: string) {
|
||||
try {
|
||||
const adminAccessToken = await this.getAdminAccessToken();
|
||||
|
||||
const options2: AxiosRequestConfig = {
|
||||
method: 'PUT',
|
||||
url: `${this.USERS_URL}/${user.id}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${adminAccessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data: {
|
||||
"username": `${user.email}`,
|
||||
// firstName:"A",
|
||||
// lastName:"B",
|
||||
"email": `${user.email}`,
|
||||
"emailVerified": true,
|
||||
"enabled": true,
|
||||
"attributes": {
|
||||
"forgot-password": [`${rstID ? rstID : "none"}`]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const userResponse = await axios.request(options2);
|
||||
|
||||
if (userResponse.status !== 204) {
|
||||
console.log("Error updating forgot-password : ");
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
|
||||
console.log("Error updating forgot password");
|
||||
console.log("Error : ", error.message);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async getMailTemplate(body: SendMailDTO, token: string, source: string): Promise<MailTemplateDTO | null> {
|
||||
|
||||
switch (body.P_MAIL_TYPE) {
|
||||
case MailTypeDTO.REGISTER_CLIENT:
|
||||
return {
|
||||
to: body.P_TO,
|
||||
subject: `🔐 Register Your Account`,
|
||||
templateName: 'a',
|
||||
variables: {
|
||||
to: body.P_TO,
|
||||
url: `https://client.alphaomegainfosys.com/register`
|
||||
}
|
||||
}
|
||||
case MailTypeDTO.FORGOT_PASSWORD:
|
||||
return {
|
||||
to: body.P_TO,
|
||||
subject: `Reset your password`,
|
||||
templateName: 'b',
|
||||
variables: {
|
||||
to: body.P_TO,
|
||||
url: `${source === 'ua' ? `https://policy.alphaomegainfosys.com/forgot-password/${token}`
|
||||
: source === 'sa' ? `https://sp.alphaomegainfosys.com/forgot-password/${token}`
|
||||
: source === 'ca' ? `https://client.alphaomegainfosys.com/forgot-password/${token}` : ''}`
|
||||
}
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async sendMail(body: SendMailDTO) {
|
||||
console.log("mail body : ", body);
|
||||
let token: string;
|
||||
let ROLE: string = "";
|
||||
let uuid: string | undefined = undefined;
|
||||
let userDetails: any | null = null;
|
||||
|
||||
if (body.P_MAIL_TYPE === MailTypeDTO.FORGOT_PASSWORD) {
|
||||
try {
|
||||
uuid = await this.generateUUID();
|
||||
|
||||
userDetails = await this.getUserDetailsByEmail(body.P_TO);
|
||||
|
||||
ROLE = userDetails.role[0];
|
||||
|
||||
} catch (error) {
|
||||
if (error instanceof BadRequestException) {
|
||||
throw error
|
||||
}
|
||||
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
token = await this.generateToken({ P_TO: body.P_TO, uuid: uuid })
|
||||
|
||||
const mailTemplate: MailTemplateDTO | null = await this.getMailTemplate(body, token, ROLE);
|
||||
|
||||
if (!mailTemplate) {
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
try {
|
||||
await this.mailService.sendMail({ ...mailTemplate });
|
||||
console.log('Email sent successfully');
|
||||
|
||||
if (body.P_MAIL_TYPE === MailTypeDTO.FORGOT_PASSWORD) {
|
||||
let forgotPasswordStatus = await this.updateForgotPassword(userDetails, uuid);
|
||||
|
||||
if (forgotPasswordStatus) {
|
||||
|
||||
return { statusCode: 200, message: 'Email sent successfully' };
|
||||
}
|
||||
|
||||
throw new InternalServerErrorException();
|
||||
|
||||
}
|
||||
return { statusCode: 200, message: 'Email sent successfully' };
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to send email:', error.message, error);
|
||||
throw new InternalServerErrorException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,34 +1,10 @@
|
||||
// import { MssqlConfig, OracleConfig } from 'ormconfig';
|
||||
import { createPool, Pool, Connection as cob } from 'oracledb';
|
||||
import { Connection, ConnectionPool } from 'mssql';
|
||||
import { createPool, Pool, Connection } from 'oracledb';
|
||||
import { ConnectionPool } from 'mssql';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { getMssqlConfig, getOracleConfig } from './db.config';
|
||||
|
||||
// @Injectable()
|
||||
// export class OracleDBService {
|
||||
// private pool: Pool;
|
||||
|
||||
// constructor() {
|
||||
// this.initializePool();
|
||||
// }
|
||||
|
||||
// private async initializePool() {
|
||||
// this.pool = await createPool({
|
||||
// ...OracleConfig,
|
||||
// poolMin: 1,
|
||||
// poolMax: 10,
|
||||
// poolIncrement: 1,
|
||||
// });
|
||||
// }
|
||||
|
||||
// async getConnection(): Promise<cob> {
|
||||
// const connection = await this.pool.getConnection();
|
||||
// return connection;
|
||||
// }
|
||||
// }
|
||||
|
||||
@Injectable()
|
||||
export class OracleDBService {
|
||||
private pool: Pool | null = null;
|
||||
|
||||
@ -30,6 +30,7 @@ export class HEADERID_DTO {
|
||||
@Min(0, { message: 'Property P_HEADERID must be at least 0 or more' })
|
||||
@IsInt({ message: 'Property P_HEADERID allows only whole numbers' })
|
||||
@IsNumber({}, { message: 'Property P_HEADERID must be a number' })
|
||||
@Transform(({ value }) => Number(value))
|
||||
@IsDefined({ message: 'Property P_HEADERID is required' })
|
||||
P_HEADERID: number;
|
||||
}
|
||||
@ -168,6 +169,35 @@ export class GLTABLE_DTO {
|
||||
P_GLTABLE: GLTABLE_ROW_DTO[];
|
||||
}
|
||||
|
||||
export class ITEMNO_DTO{
|
||||
@ApiProperty({ required: true })
|
||||
@Max(99999, { message: 'Property ITEMNO must not exceed 99999' })
|
||||
@Min(0, { message: 'Property ITEMNO must be at least 0 or more' })
|
||||
@IsInt({ message: 'Property ITEMNO allows only whole numbers' })
|
||||
@Transform(({ value }) => Number(value))
|
||||
@IsNumber({}, { message: 'Property ITEMNO must be a number' })
|
||||
@IsDefined({ message: 'Property ITEMNO is required' })
|
||||
P_ITEMNO: number;
|
||||
}
|
||||
|
||||
export class SHIPCONTACTID_DTO{
|
||||
@ApiProperty({ required: true })
|
||||
@Max(99999, { message: 'Property P_SHIPCONTACTID must not exceed 99999' })
|
||||
@Min(0, { message: 'Property P_SHIPCONTACTID must be at least 0 or more' })
|
||||
@IsInt({ message: 'Property P_SHIPCONTACTID allows only whole numbers' })
|
||||
@Transform(({ value }) => Number(value))
|
||||
@IsNumber({}, { message: 'Property P_SHIPCONTACTID must be a number' })
|
||||
@IsDefined({ message: 'Property P_SHIPCONTACTID is required' })
|
||||
P_SHIPCONTACTID: number;
|
||||
}
|
||||
|
||||
export class SHIPNAME_DTO {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString({ message: 'Property P_SHIPNAME must be a string' })
|
||||
@IsDefined({ message: 'Property P_SHIPNAME is required' })
|
||||
P_SHIPNAME: string;
|
||||
}
|
||||
|
||||
export class USSETS_DTO {
|
||||
@ApiProperty({ required: true })
|
||||
// @Max(99999, { message: 'Property P_USSETS must not exceed 99999' })
|
||||
|
||||
@ -4,15 +4,16 @@ import {
|
||||
APPLICATIONNAME_DTO, AUTHREP_DTO, AUTO_FLAG_DTO, COMMERCIAL_SAMPLE_FLAG_DTO,
|
||||
COUNTRYTABLE_DTO, CUSTCOURIERNO_DTO, DELIVERYMETHOD_DTO, DELIVERYTYPE_DTO,
|
||||
EXIBITIONS_FAIR_FLAG_DTO, FORMOFSECURITY_DTO, GLTABLE_DTO, HEADERID_DTO,
|
||||
HORSE_FLAG_DTO, INSPROTECTION_DTO, LDIPROTECTION_DTO, ORDERTYPE_DTO, PAYMENTMETHOD_DTO,
|
||||
PROF_EQUIPMENT_FLAG_DTO, REFNO_DTO, SHIPADDRID_DTO, SHIPTOTYPE_DTO, USSETS_DTO
|
||||
HORSE_FLAG_DTO, INSPROTECTION_DTO, ITEMNO_DTO, LDIPROTECTION_DTO, ORDERTYPE_DTO, PAYMENTMETHOD_DTO,
|
||||
PROF_EQUIPMENT_FLAG_DTO, REFNO_DTO, SHIPADDRID_DTO, SHIPCONTACTID_DTO, SHIPNAME_DTO, SHIPTOTYPE_DTO, USSETS_DTO
|
||||
} from "./carnet-application-property.dto";
|
||||
|
||||
import { NOTES_DTO, SPID_DTO, USERID_DTO } from "../uscib-managed-sp/sp/sp-property.dto";
|
||||
import { ADDRESS1_DTO, ADDRESS2_DTO, CITY_DTO, COUNTRY_DTO, NOTES_DTO, SPID_DTO, STATE_DTO, USERID_DTO, ZIP_DTO } from "../uscib-managed-sp/sp/sp-property.dto";
|
||||
|
||||
import { CLIENTID_DTO } from "../manage-clients/manage-clients-property.dto";
|
||||
|
||||
import { HOLDERID_DTO, LOCATIONID_DTO } from "../manage-holders/manage-holders-property.dto";
|
||||
import { EMAIL_ADDRESS_DTO, FAX_NO_DTO, FIRSTNAME_DTO, LASTNAME_DTO, MIDDLE_INITIAL_DTO, MOBILE_NO_DTO, PHONE_NO_DTO, TITLE_DTO } from "../property.dto";
|
||||
|
||||
|
||||
export class SaveCarnetApplicationDTO extends IntersectionType(
|
||||
@ -72,13 +73,26 @@ export class AddGenerallistItemsDTO extends IntersectionType(
|
||||
HEADERID_DTO, GLTABLE_DTO, USERID_DTO
|
||||
) { }
|
||||
|
||||
export class DeleteGenerallistItemsDTO extends IntersectionType(
|
||||
HEADERID_DTO, ITEMNO_DTO, USERID_DTO
|
||||
) { }
|
||||
|
||||
export class AddCountriesDTO extends IntersectionType(
|
||||
HEADERID_DTO, USSETS_DTO, COUNTRYTABLE_DTO, USERID_DTO
|
||||
) { }
|
||||
|
||||
export class UpdateShippingDetailsDTO extends IntersectionType(
|
||||
HEADERID_DTO, SHIPTOTYPE_DTO, SHIPADDRID_DTO, FORMOFSECURITY_DTO,
|
||||
INSPROTECTION_DTO, LDIPROTECTION_DTO, DELIVERYTYPE_DTO, DELIVERYMETHOD_DTO,
|
||||
PAYMENTMETHOD_DTO, CUSTCOURIERNO_DTO, REFNO_DTO, NOTES_DTO, USERID_DTO
|
||||
HEADERID_DTO,
|
||||
PartialType(SHIPTOTYPE_DTO), PartialType(SHIPCONTACTID_DTO), PartialType(SHIPNAME_DTO),
|
||||
PartialType(ADDRESS1_DTO), PartialType(ADDRESS2_DTO), PartialType(CITY_DTO), PartialType(STATE_DTO), PartialType(ZIP_DTO), PartialType(COUNTRY_DTO),
|
||||
PartialType(FIRSTNAME_DTO), PartialType(LASTNAME_DTO), PartialType(TITLE_DTO), PartialType(PHONE_NO_DTO), PartialType(MOBILE_NO_DTO), PartialType(FAX_NO_DTO), PartialType(EMAIL_ADDRESS_DTO), PartialType(MIDDLE_INITIAL_DTO),
|
||||
PartialType(FORMOFSECURITY_DTO), PartialType(INSPROTECTION_DTO), PartialType(LDIPROTECTION_DTO),
|
||||
PartialType(DELIVERYTYPE_DTO), PartialType(DELIVERYMETHOD_DTO), PartialType(PAYMENTMETHOD_DTO),
|
||||
PartialType(CUSTCOURIERNO_DTO), PartialType(REFNO_DTO), PartialType(NOTES_DTO),
|
||||
USERID_DTO
|
||||
) { }
|
||||
|
||||
export class GetCarnetControlCenterDTO extends IntersectionType(
|
||||
SPID_DTO, USERID_DTO, HEADERID_DTO
|
||||
) { }
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { IntersectionType, PartialType } from "@nestjs/swagger";
|
||||
|
||||
import { CONTACTSTABLE_DTO } from "../manage-holders/manage-holders-property.dto";
|
||||
import { CONTACTSTABLE_DTO, LOCATIONID_DTO } from "../manage-holders/manage-holders-property.dto";
|
||||
|
||||
import {
|
||||
DEFAULT_CONTACT_FLAG_DTO, EMAIL_ADDRESS_DTO, FAX_NO_DTO, FIRSTNAME_DTO, LASTNAME_DTO,
|
||||
@ -102,7 +102,7 @@ export class UpdateClientLocationsDTO extends IntersectionType(
|
||||
|
||||
export class CreateClientContactsDTO extends IntersectionType(
|
||||
SPID_DTO,
|
||||
CLIENTID_DTO,
|
||||
LOCATIONID_DTO,
|
||||
CONTACTSTABLE_DTO,
|
||||
DEFAULT_CONTACT_FLAG_DTO,
|
||||
USERID_DTO
|
||||
@ -120,6 +120,10 @@ export class GetClientDTO extends IntersectionType(
|
||||
CLIENTID_DTO
|
||||
) { }
|
||||
|
||||
export class GetClientContactByLacationIdDTO extends IntersectionType(
|
||||
SPID_DTO, LOCATIONID_DTO
|
||||
){}
|
||||
|
||||
export class ClientContactControlsDTO extends IntersectionType(
|
||||
SPID_DTO,
|
||||
CLIENT_CONTACTID_DTO,
|
||||
|
||||
@ -44,6 +44,7 @@ export class HOLDERID_DTO {
|
||||
@Min(0, { message: 'Property P_HOLDERID must be at least 0 or more' })
|
||||
@IsInt({ message: 'Property P_HOLDERID allows only whole numbers' })
|
||||
@IsNumber({}, { message: 'Property P_HOLDERID must be a number' })
|
||||
@Transform(({ value }) => Number(value))
|
||||
@IsDefined({ message: 'Property P_HOLDERID is required' })
|
||||
P_HOLDERID: number;
|
||||
}
|
||||
@ -58,7 +59,7 @@ export class HOLDERNO_DTO {
|
||||
|
||||
export class HOLDERTYPE_DTO {
|
||||
@ApiProperty({ required: true })
|
||||
@Length(0, 3, { message: 'Property P_HOLDERTYPE must be between 0 to 3 characters' })
|
||||
@Length(0, 4, { message: 'Property P_HOLDERTYPE must be between 0 to 6 characters' })
|
||||
@IsString({ message: 'Property P_HOLDERTYPE must be a string' })
|
||||
@IsDefined({ message: 'Property P_HOLDERTYPE is required' })
|
||||
P_HOLDERTYPE: string;
|
||||
@ -115,6 +116,7 @@ export class HOLDERCONTACTID_DTO {
|
||||
@Min(0, { message: 'Property P_HOLDERCONTACTID must be at least 0 or more' })
|
||||
@IsInt({ message: 'Property P_HOLDERCONTACTID allows only whole numbers' })
|
||||
@IsNumber({}, { message: 'Property P_HOLDERCONTACTID must be a number' })
|
||||
@Transform(({ value }) => Number(value))
|
||||
@IsDefined({ message: 'Property P_HOLDERCONTACTID is required' })
|
||||
P_HOLDERCONTACTID: number;
|
||||
}
|
||||
|
||||
@ -96,5 +96,5 @@ export class HolderContactActivateOrInactivateDTO extends IntersectionType(
|
||||
|
||||
export class SearchHolderDTO extends IntersectionType(
|
||||
SPID_DTO,
|
||||
HOLDERNAME_DTO
|
||||
PartialType(HOLDERNAME_DTO)
|
||||
) { }
|
||||
46
src/filters/auth-exception.filter.ts
Normal file
46
src/filters/auth-exception.filter.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import {
|
||||
ExceptionFilter,
|
||||
Catch,
|
||||
ArgumentsHost,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { Response } from 'express';
|
||||
|
||||
@Catch(UnauthorizedException)
|
||||
export class AuthExceptionFilter implements ExceptionFilter {
|
||||
catch(exception: UnauthorizedException, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp();
|
||||
const response = ctx.getResponse<Response>();
|
||||
|
||||
const status = exception.getStatus();
|
||||
const message = exception.message || 'Unauthorized';
|
||||
|
||||
// Check if message matches specific condition
|
||||
if (message.toLocaleLowerCase() === 'authentication failed') {
|
||||
// Clear cookies
|
||||
response.clearCookie('access_token', {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: 'none',
|
||||
});
|
||||
|
||||
response.clearCookie('refresh_token', {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: 'none',
|
||||
});
|
||||
|
||||
// Send custom response
|
||||
return response.status(status).json({
|
||||
statusCode: status,
|
||||
message: 'Authentication failed',
|
||||
});
|
||||
}
|
||||
|
||||
// If not a match, fallback to default response
|
||||
return response.status(status).json({
|
||||
statusCode: status,
|
||||
message,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -6,41 +6,48 @@ import {
|
||||
Global,
|
||||
} from '@nestjs/common';
|
||||
import { AuthService } from 'src/auth/auth.service';
|
||||
import * as jwt from 'jsonwebtoken';
|
||||
import { InternalServerException } from 'src/exceptions/internalServerError.exception';
|
||||
import { UnauthorizedException as UE } from 'src/exceptions/unauthorized.exception';
|
||||
import { MailTypeDTO } from 'src/auth/auth.dto';
|
||||
|
||||
@Global()
|
||||
@Injectable()
|
||||
export class JwtAuthGuard implements CanActivate {
|
||||
constructor(private readonly authService: AuthService) {}
|
||||
constructor(private readonly authService: AuthService) { }
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
|
||||
// Read token from cookie
|
||||
console.log('------------------------------');
|
||||
let g = await request.cookies
|
||||
console.log("g : ",g);
|
||||
console.log(' guard cookies ------------------------------');
|
||||
|
||||
const token = request.cookies?.access_token;
|
||||
|
||||
const body = request.body;
|
||||
|
||||
console.log("from JWT guard body : ", body);
|
||||
|
||||
|
||||
if (body?.P_MAIL_TYPE && body?.P_MAIL_TYPE === MailTypeDTO.FORGOT_PASSWORD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
console.log('error from inspect token .....');
|
||||
|
||||
console.log("No token found from Request");
|
||||
throw new UnauthorizedException('Authentication failed');
|
||||
}
|
||||
|
||||
try {
|
||||
const decoded = await this.authService.decodeToken(token);
|
||||
request.user = decoded;
|
||||
const verifiedUser = await this.authService.decodeToken(token);
|
||||
request.user = verifiedUser;
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.log("error in jwt-auth guard below decode : ",err.message);
|
||||
} catch (error) {
|
||||
if (error instanceof jwt.TokenExpiredError || error instanceof jwt.JsonWebTokenError || error instanceof jwt.NotBeforeError) {
|
||||
throw new UnauthorizedException('Invalid Token');
|
||||
}
|
||||
|
||||
throw new UnauthorizedException({
|
||||
message: 'Invalid Token',
|
||||
error: 'Unauthorized',
|
||||
statusCode: 401,
|
||||
});
|
||||
if (error instanceof UnauthorizedException || error instanceof UE) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new InternalServerException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Inject,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
@ -10,44 +11,28 @@ import { Request } from 'express';
|
||||
|
||||
@Injectable()
|
||||
export class RegisterGuard implements CanActivate {
|
||||
constructor(private readonly jwtService: JwtService) {}
|
||||
constructor(
|
||||
@Inject("REGISTER_VERIFY_JWT") readonly REGISTER_VERIFY_JWT: JwtService
|
||||
) { }
|
||||
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const request = context.switchToHttp().getRequest<Request>();
|
||||
const authHeader = request.headers['authorization'];
|
||||
|
||||
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||
throw new UnauthorizedException('Authorization header missing or malformed');
|
||||
throw new UnauthorizedException('Invalid Request');
|
||||
}
|
||||
|
||||
const token = authHeader.split(' ')[1];
|
||||
|
||||
try {
|
||||
// Decode without verifying to check expiry
|
||||
const decoded: any = this.jwtService.decode(token);
|
||||
|
||||
console.log(decoded);
|
||||
|
||||
|
||||
if (!decoded || !decoded.exp) {
|
||||
throw new UnauthorizedException('Invalid token payload');
|
||||
}
|
||||
|
||||
// Check expiration (exp is in seconds, Date.now() in ms)
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
if (decoded.exp < now) {
|
||||
throw new UnauthorizedException('Token expired');
|
||||
}
|
||||
|
||||
// Verify the token (checks signature and expiration again)
|
||||
this.jwtService.verify(token, {secret:'yourSecretKey'});
|
||||
|
||||
// Optionally attach user info to request object for further use
|
||||
request['user'] = decoded;
|
||||
|
||||
const payload = this.REGISTER_VERIFY_JWT.verify(token);
|
||||
request['user'] = payload;
|
||||
return true;
|
||||
} catch (err) {
|
||||
throw new UnauthorizedException('Invalid or expired token');
|
||||
console.log("Error in register guard : ", err.message);
|
||||
|
||||
throw new UnauthorizedException("Invalid Register Token");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import { Reflector } from '@nestjs/core';
|
||||
import { ROLES_KEY } from '../decorators/roles.decorator';
|
||||
import * as jwt from 'jsonwebtoken';
|
||||
import { UnauthorizedException } from 'src/exceptions/unauthorized.exception';
|
||||
import { MailTypeDTO } from 'src/auth/auth.dto';
|
||||
|
||||
@Injectable()
|
||||
export class RolesGuard implements CanActivate {
|
||||
@ -24,6 +25,14 @@ export class RolesGuard implements CanActivate {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const token = request.cookies?.access_token; // Token is stored as HttpOnly cookie
|
||||
|
||||
const body = request.body;
|
||||
|
||||
console.log("from JWT guard body : ", body);
|
||||
|
||||
if (body?.P_MAIL_TYPE && body?.P_MAIL_TYPE === MailTypeDTO.FORGOT_PASSWORD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
throw new UnauthorizedException('Authentication Failed');
|
||||
}
|
||||
|
||||
@ -20,6 +20,9 @@ export class LogoutInterceptor implements NestInterceptor {
|
||||
response.clearCookie('access_token');
|
||||
response.clearCookie('refresh_token');
|
||||
|
||||
console.log("No tokens found so logging-out");
|
||||
|
||||
|
||||
response.status(200).json({
|
||||
statusCode: 200,
|
||||
message: 'Logged-Out successfully',
|
||||
|
||||
@ -1,18 +1,49 @@
|
||||
import { MailerModule } from '@nestjs-modules/mailer';
|
||||
|
||||
import { Module } from '@nestjs/common';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { join } from 'path';
|
||||
import * as Joi from 'joi';
|
||||
import { MailService } from './mail.service';
|
||||
import * as nodemailer from 'nodemailer';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
MailerModule.forRoot({
|
||||
transport: {
|
||||
host: 'localhost',
|
||||
port: 1025,
|
||||
ignoreTLS: true,
|
||||
},
|
||||
defaults: {
|
||||
from: '"No Reply" <no-reply@example.com>',
|
||||
},
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
validationSchema: Joi.object({
|
||||
MAIL_USER: Joi.string().required(),
|
||||
MAIL_PASS: Joi.string().required(),
|
||||
}),
|
||||
}),
|
||||
],
|
||||
|
||||
providers: [
|
||||
{
|
||||
provide: 'MAIL_TRANSPORTER',
|
||||
useFactory: async (configService: ConfigService) => {
|
||||
return nodemailer.createTransport(
|
||||
{
|
||||
// service: "gmail",
|
||||
host: 'smtp.gmail.com',
|
||||
port: 587,
|
||||
secure: false,
|
||||
auth: {
|
||||
user: configService.get<string>('MAIL_USER'),
|
||||
pass: configService.get<string>('MAIL_PASS'),
|
||||
},
|
||||
},
|
||||
{
|
||||
from: `"Carnet APP" <${configService.get<string>('MAIL_USER')}>`,
|
||||
}
|
||||
);
|
||||
},
|
||||
inject: [ConfigService],
|
||||
},
|
||||
MailService,
|
||||
],
|
||||
exports: [MailService],
|
||||
|
||||
|
||||
})
|
||||
|
||||
export class MailModule { }
|
||||
|
||||
42
src/mail/mail.service.ts
Normal file
42
src/mail/mail.service.ts
Normal file
@ -0,0 +1,42 @@
|
||||
// mailer.service.ts
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Transporter } from 'nodemailer';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as Handlebars from 'handlebars';
|
||||
import { MailTemplateDTO } from 'src/auth/auth.dto';
|
||||
|
||||
@Injectable()
|
||||
export class MailService {
|
||||
private templatesCache = new Map<string, Handlebars.TemplateDelegate>();
|
||||
|
||||
constructor(@Inject('MAIL_TRANSPORTER') private readonly transporter: Transporter) {
|
||||
console.log(path.join(process.cwd(), 'public', 'mail-templates', 'a.hbs'));
|
||||
|
||||
}
|
||||
|
||||
private loadTemplate(templateName: string): Handlebars.TemplateDelegate {
|
||||
if (this.templatesCache.has(templateName)) {
|
||||
return this.templatesCache.get(templateName)!;
|
||||
}
|
||||
|
||||
const templatePath = path.join(process.cwd(), 'public', 'mail-templates', `${templateName}.hbs`);
|
||||
const source = fs.readFileSync(templatePath, 'utf8');
|
||||
const compiled = Handlebars.compile(source);
|
||||
this.templatesCache.set(templateName, compiled);
|
||||
return compiled;
|
||||
}
|
||||
|
||||
async sendMail(data: MailTemplateDTO) {
|
||||
const template = this.loadTemplate(data.templateName);
|
||||
const html = template(data.variables);
|
||||
|
||||
const mailOptions = {
|
||||
to: data.to,
|
||||
subject: data.subject,
|
||||
html,
|
||||
};
|
||||
|
||||
return this.transporter.sendMail(mailOptions);
|
||||
}
|
||||
}
|
||||
11
src/main.ts
11
src/main.ts
@ -8,13 +8,20 @@ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||
import { SwaggerDocumentOptions } from '@nestjs/swagger';
|
||||
import { BadRequestException } from './exceptions/badRequest.exception';
|
||||
import * as cookieParser from 'cookie-parser';
|
||||
import { AuthExceptionFilter } from './filters/auth-exception.filter';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule, {
|
||||
logger: ['error', 'warn'],
|
||||
cors: {
|
||||
// origin: 'https://dev.alphaomegainfosys.com/',
|
||||
origin: ['http://localhost:3000', 'http://localhost:5173'],
|
||||
origin: [
|
||||
'http://localhost:3000',
|
||||
'http://localhost:5173',
|
||||
'https://policy.alphaomegainfosys.com',
|
||||
'https://sp.alphaomegainfosys.com',
|
||||
'https://client.alphaomegainfosys.com'
|
||||
],
|
||||
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 204,
|
||||
@ -24,6 +31,8 @@ async function bootstrap() {
|
||||
|
||||
app.use(cookieParser());
|
||||
|
||||
app.useGlobalFilters(new AuthExceptionFilter());
|
||||
|
||||
|
||||
function extractConstraints(validationErrors: ValidationError[]) {
|
||||
const constraints: { [key: string]: string }[] = [];
|
||||
|
||||
@ -47,7 +47,7 @@ export class ManageClientsService {
|
||||
|
||||
const finalBody: CreateClientDataDTO = { ...newBody, ...reqBody };
|
||||
|
||||
let connection: Connection; // Fixed duplicate declaration
|
||||
let connection: mssql.ConnectionPool; // Fixed duplicate declaration
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -98,7 +98,7 @@ export class ManageClientsService {
|
||||
};
|
||||
|
||||
GetPreparerByClientid = async (body: GetClientDTO) => {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -142,7 +142,7 @@ export class ManageClientsService {
|
||||
|
||||
const finalBody: UpdateClientDTO = { ...newBody, ...reqBody };
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
@ -196,12 +196,12 @@ export class ManageClientsService {
|
||||
...reqBody,
|
||||
};
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
request.input('P_SPID', mssql.Int, finalBody.P_SPID);
|
||||
request.input('P_CLIENTID', mssql.Int, finalBody.P_CLIENTID);
|
||||
request.input('P_LOCATIONID', mssql.Int, finalBody.P_LOCATIONID);
|
||||
|
||||
const contactTable = new mssql.Table('carnetsys.ContactsTable');
|
||||
contactTable.create = true;
|
||||
@ -272,7 +272,7 @@ export class ManageClientsService {
|
||||
|
||||
const finalBody: UpdateClientContactsDTO = { ...newBody, ...reqBody };
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -327,7 +327,7 @@ export class ManageClientsService {
|
||||
|
||||
const finalBody: UpdateClientLocationsDTO = { ...newBody, ...reqBody };
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -379,7 +379,7 @@ export class ManageClientsService {
|
||||
...reqBody,
|
||||
};
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -452,7 +452,7 @@ export class ManageClientsService {
|
||||
...reqBody,
|
||||
};
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -505,7 +505,7 @@ export class ManageClientsService {
|
||||
...reqBody,
|
||||
};
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -553,7 +553,7 @@ export class ManageClientsService {
|
||||
...reqBody,
|
||||
};
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
|
||||
@ -20,7 +20,7 @@ export class ManageFeeService {
|
||||
// Basic Fee Setup
|
||||
|
||||
async GETBASICFEERATES(body: GetFeeGeneralDTO): Promise<any[] | Object> {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -41,7 +41,7 @@ export class ManageFeeService {
|
||||
}
|
||||
|
||||
async CREATEBASICFEE(body: CreateBasicFeeDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -63,7 +63,7 @@ export class ManageFeeService {
|
||||
}
|
||||
|
||||
async UPDATEBASICFEE(body: UpdateBasicFeeDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -86,7 +86,7 @@ export class ManageFeeService {
|
||||
|
||||
async GETBONDRATES(body: GetFeeGeneralDTO): Promise<any[] | object> {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -111,7 +111,7 @@ export class ManageFeeService {
|
||||
|
||||
async CREATEBONDRATE(body: CreateBondRateDTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -138,7 +138,7 @@ export class ManageFeeService {
|
||||
|
||||
async UPDATEBONDRATE(body: UpdateBondRateDTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -161,7 +161,7 @@ export class ManageFeeService {
|
||||
// CArgo Rate
|
||||
|
||||
async GETCARGORATES(body: GetFeeGeneralDTO): Promise<any[] | object> {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -185,7 +185,7 @@ export class ManageFeeService {
|
||||
}
|
||||
|
||||
async CREATECARGORATE(body: CreateCargoRateDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -209,7 +209,7 @@ export class ManageFeeService {
|
||||
}
|
||||
|
||||
async UPDATECARGORATE(body: UpdateCargoRateDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -233,7 +233,7 @@ export class ManageFeeService {
|
||||
|
||||
async GETCFFEERATES(body: GetFeeGeneralDTO): Promise<any[]> {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -258,7 +258,7 @@ export class ManageFeeService {
|
||||
|
||||
async CREATECFFEE(body: CreateCfFeeDTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -285,7 +285,7 @@ export class ManageFeeService {
|
||||
|
||||
async UPDATECFFEE(body: UpdateCfFeeDTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -308,7 +308,7 @@ export class ManageFeeService {
|
||||
// Continuation sheet
|
||||
|
||||
async GETCSFEERATES(body: GetFeeGeneralDTO): Promise<any[]> {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -333,7 +333,7 @@ export class ManageFeeService {
|
||||
}
|
||||
|
||||
async CREATECSFEE(body: CreateCsFeeDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -357,7 +357,7 @@ export class ManageFeeService {
|
||||
}
|
||||
|
||||
async UPDATECSFEE(body: UpdateCsFeeDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -381,7 +381,7 @@ export class ManageFeeService {
|
||||
|
||||
async GETEFFEERATES(body: GetFeeGeneralDTO): Promise<any[]> {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -405,7 +405,7 @@ export class ManageFeeService {
|
||||
}
|
||||
|
||||
async CREATEEFFEE(body: CreateEfFeeDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -432,7 +432,7 @@ export class ManageFeeService {
|
||||
|
||||
async UPDATEEFFEE(body: UpdateEfFeeDTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -456,7 +456,7 @@ export class ManageFeeService {
|
||||
|
||||
async GETFEECOMM(body: GetFeeGeneralDTO): Promise<any[]> {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -483,7 +483,7 @@ export class ManageFeeService {
|
||||
|
||||
async CREATEFEECOMM(body: CreateFeeCommDTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -507,7 +507,7 @@ export class ManageFeeService {
|
||||
}
|
||||
|
||||
async UPDATEFEECOMM(body: UpdateFeeCommDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
|
||||
@ -45,7 +45,7 @@ export class ManageHoldersService {
|
||||
|
||||
const finalBody: CreateHoldersDTO = { ...newBody, ...reqBody };
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new Request(connection);
|
||||
@ -103,7 +103,7 @@ export class ManageHoldersService {
|
||||
};
|
||||
|
||||
GetHolderRecord = async (body: GetHolderDTO) => {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new Request(connection);
|
||||
@ -119,7 +119,7 @@ export class ManageHoldersService {
|
||||
};
|
||||
|
||||
UpdateHolder = async (body: UpdateHolderDTO) => {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new mssql.Request(connection);
|
||||
@ -153,7 +153,7 @@ export class ManageHoldersService {
|
||||
|
||||
UpdateHolderContact = async (body: UpdateHolderContactDTO) => {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new mssql.Request(connection);
|
||||
@ -181,7 +181,7 @@ export class ManageHoldersService {
|
||||
|
||||
GetHolderContacts = async (body: GetHolderDTO) => {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new Request(connection);
|
||||
@ -200,7 +200,7 @@ export class ManageHoldersService {
|
||||
|
||||
console.log(body);
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new Request(connection);
|
||||
@ -216,7 +216,7 @@ export class ManageHoldersService {
|
||||
};
|
||||
|
||||
ReactivateHolder = async (body: HolderActivateOrInactivateDTO) => {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new Request(connection);
|
||||
@ -233,7 +233,7 @@ export class ManageHoldersService {
|
||||
};
|
||||
|
||||
InactivateHolderContact = async (body: HolderContactActivateOrInactivateDTO) => {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new Request(connection);
|
||||
@ -250,7 +250,7 @@ export class ManageHoldersService {
|
||||
};
|
||||
|
||||
ReactivateHolderContact = async (body: HolderContactActivateOrInactivateDTO) => {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request: Request = new Request(connection);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Connection, Request } from 'mssql';
|
||||
import { MssqlDBService } from 'src/db/db.service';
|
||||
import * as mssql from 'mssql';
|
||||
|
||||
@Injectable()
|
||||
export class MssqlService {
|
||||
@ -8,7 +9,7 @@ export class MssqlService {
|
||||
constructor(private readonly mssqlDBService: MssqlDBService) { }
|
||||
|
||||
async checkConnection() {
|
||||
let connection : Connection;
|
||||
let connection : mssql.ConnectionPool;
|
||||
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
|
||||
@ -20,7 +20,7 @@ export class ParamTableService {
|
||||
console.log(finalBody);
|
||||
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -35,7 +35,7 @@ export class ParamTableService {
|
||||
}
|
||||
|
||||
async CREATETABLERECORD(body: CreateTableRecordDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -57,7 +57,7 @@ export class ParamTableService {
|
||||
}
|
||||
|
||||
async CREATEPARAMRECORD(body: CreateParamRecordDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -87,7 +87,7 @@ export class ParamTableService {
|
||||
}
|
||||
|
||||
async UPDATEPARAMRECORD(body: UpdateParamRecordDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -116,7 +116,7 @@ export class ParamTableService {
|
||||
|
||||
async INACTIVATEPARAMRECORD(body: ActivateOrInactivateParamRecordDTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -136,7 +136,7 @@ export class ParamTableService {
|
||||
}
|
||||
|
||||
async REACTIVATEPARAMRECORD(body: ActivateOrInactivateParamRecordDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
|
||||
@ -12,7 +12,7 @@ export class CarnetSequenceService {
|
||||
|
||||
async getCarnetSequence(body: SPID_DTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -26,7 +26,7 @@ export class CarnetSequenceService {
|
||||
}
|
||||
|
||||
async createCarnetSequence(body: CreateCarnetSequenceDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
|
||||
@ -11,7 +11,7 @@ export class RegionService {
|
||||
constructor(private readonly mssqlDBService: MssqlDBService) { }
|
||||
|
||||
async getRegions() {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -24,7 +24,7 @@ export class RegionService {
|
||||
|
||||
async insetNewRegions(body: InsertRegionsDto) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -39,7 +39,7 @@ export class RegionService {
|
||||
}
|
||||
|
||||
async updateRegions(body: UpdateRegionDto){
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
|
||||
@ -15,7 +15,7 @@ export class SpContactsService {
|
||||
|
||||
async getSpAllContacts(body: SPID_DTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -30,7 +30,7 @@ export class SpContactsService {
|
||||
|
||||
async getSPDefaultcontacts(body: SPID_DTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -45,7 +45,7 @@ export class SpContactsService {
|
||||
|
||||
async inactivateSPContact(body: SP_CONTACTID_DTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -59,7 +59,7 @@ export class SpContactsService {
|
||||
}
|
||||
|
||||
async insertSPContacts(body: InsertSPContactsDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -83,7 +83,7 @@ export class SpContactsService {
|
||||
}
|
||||
|
||||
async setSPDefaultcontact(body: SP_CONTACTID_DTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -97,7 +97,7 @@ export class SpContactsService {
|
||||
}
|
||||
|
||||
async updateSPContacts(body: UpdateSPContactsDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
|
||||
@ -12,7 +12,7 @@ export class SpService {
|
||||
|
||||
async getAllServiceproviders() {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -26,7 +26,7 @@ export class SpService {
|
||||
|
||||
async getSpBySpid(body: SPID_DTO) {
|
||||
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -40,7 +40,7 @@ export class SpService {
|
||||
}
|
||||
|
||||
async insertNewServiceProvider(body: InsertNewServiceProviderDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
@ -69,7 +69,7 @@ export class SpService {
|
||||
}
|
||||
|
||||
async updateServiceProvider(body: UpdateServiceProviderDTO) {
|
||||
let connection: Connection;
|
||||
let connection: mssql.ConnectionPool;
|
||||
try {
|
||||
connection = await this.mssqlDBService.getConnection();
|
||||
const request = new Request(connection);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Body, Controller, Patch, Post, Put, UseGuards } from '@nestjs/common';
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post, Put, UseGuards } from '@nestjs/common';
|
||||
import { CarnetApplicationService } from './carnet-application.service';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
AddCountriesDTO,
|
||||
AddGenerallistItemsDTO,
|
||||
CA_UpdateHolderDTO,
|
||||
CarnetProcessingCenterDTO, CreateApplicationDTO, SaveCarnetApplicationDTO, TransmitApplicationtoProcessDTO,
|
||||
CarnetProcessingCenterDTO, CreateApplicationDTO, DeleteGenerallistItemsDTO, GetCarnetControlCenterDTO, SaveCarnetApplicationDTO, TransmitApplicationtoProcessDTO,
|
||||
UpdateExpGoodsAuthRepDTO,
|
||||
UpdateShippingDetailsDTO
|
||||
} from 'src/dto/property.dto';
|
||||
@ -63,16 +63,31 @@ export class CarnetApplicationController {
|
||||
return this.carnetApplicationService.AddCountries(body);
|
||||
}
|
||||
|
||||
@Put('EditGenerallistItems')
|
||||
EditGenerallistItems(@Body() body: AddGenerallistItemsDTO) {
|
||||
return this.carnetApplicationService.EditGenerallistItems(body);
|
||||
}
|
||||
|
||||
@Delete('DeleteGenerallistItems')
|
||||
DeleteGenerallistItems(@Body() body: DeleteGenerallistItemsDTO) {
|
||||
return this.carnetApplicationService.DeleteGenerallistItems(body);
|
||||
}
|
||||
|
||||
@Patch('UpdateShippingDetails')
|
||||
UpdateShippingDetails(@Body() body: UpdateShippingDetailsDTO) {
|
||||
return this.carnetApplicationService.UpdateShippingDetails(body);
|
||||
}
|
||||
|
||||
@Get('EstimatedFees/:P_SPID/:P_USERID/:P_HEADERID')
|
||||
EstimatedFees(@Param() body: GetCarnetControlCenterDTO) {
|
||||
return this.carnetApplicationService.EstimatedFees(body);
|
||||
}
|
||||
|
||||
// processing [ PROCESSINGCENTER_PKG ]
|
||||
|
||||
@Patch('ProcessOriginalCarnet')
|
||||
@Patch('ProcessCarnet')
|
||||
ProcessOriginalCarnet(@Body() body: CarnetProcessingCenterDTO) {
|
||||
return this.carnetApplicationService.ProcessOriginalCarnet(body);
|
||||
return this.carnetApplicationService.ProcessCarnet(body);
|
||||
}
|
||||
|
||||
@Patch('UpdatePrintCarnet')
|
||||
@ -97,4 +112,35 @@ export class CarnetApplicationController {
|
||||
CloseCarnet(@Body() body: CarnetProcessingCenterDTO) {
|
||||
return this.carnetApplicationService.CloseCarnet(body);
|
||||
}
|
||||
|
||||
// [ CARNETCONTROLCENTER_PKG ]
|
||||
|
||||
@Get('GetHolderstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||
GetHolderstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||
return this.carnetApplicationService.GetHolderstoEdit(body);
|
||||
}
|
||||
|
||||
@Get('GetGoodsDetailstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||
GetGoodsDetailstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||
return this.carnetApplicationService.GetGoodsDetailstoEdit(body);
|
||||
}
|
||||
|
||||
@Get('GetGoodsItemstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||
GetGoodsItemstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||
return this.carnetApplicationService.GetGoodsItemstoEdit(body);
|
||||
}
|
||||
|
||||
@Get('GetCountryDetailstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||
GetCountryDetailstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||
return this.carnetApplicationService.GetCountryDetailstoEdit(body);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Get('GetShipPaymentDetailstoEdit/:P_SPID/:P_USERID/:P_HEADERID')
|
||||
GetShipPaymentDetailstoEdit(@Param() body: GetCarnetControlCenterDTO) {
|
||||
return this.carnetApplicationService.GetShipPaymentDetailstoEdit(body);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -11,9 +11,12 @@ import {
|
||||
AddGenerallistItemsDTO,
|
||||
AddCountriesDTO,
|
||||
UpdateShippingDetailsDTO,
|
||||
CA_UpdateHolderDTO
|
||||
CA_UpdateHolderDTO,
|
||||
GetCarnetControlCenterDTO,
|
||||
DeleteGenerallistItemsDTO
|
||||
} from 'src/dto/property.dto';
|
||||
import { OracleService } from '../oracle.service';
|
||||
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||
|
||||
@Injectable()
|
||||
export class CarnetApplicationService {
|
||||
@ -217,7 +220,14 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Saved Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -254,7 +264,14 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Transmitted Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -271,7 +288,7 @@ export class CarnetApplicationService {
|
||||
`BEGIN
|
||||
CARNETAPPLICATION_PKG.CreateApplication(
|
||||
:P_SPID, :P_CLIENTID, :P_LOCATIONID, :P_USERID,
|
||||
:P_APPLICATIONNAME, :P_ORDERTYPE, :P_ERRORMESG
|
||||
:P_APPLICATIONNAME, :P_ORDERTYPE, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
@ -281,8 +298,8 @@ export class CarnetApplicationService {
|
||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_APPLICATIONNAME: { val: body.P_APPLICATIONNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ORDERTYPE: { val: body.P_ORDERTYPE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ERRORMESG: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||
// P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
// P_ERRORMESG: { dir: oracledb.BIND_OUT, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
@ -290,12 +307,19 @@ export class CarnetApplicationService {
|
||||
await connection.commit();
|
||||
|
||||
const outBinds = result.outBinds;
|
||||
if (!outBinds?.P_ERRORMESG) {
|
||||
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_ERRORMESG, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 201, message: "Application created successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -331,7 +355,15 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_ERRORMESG, CarnetApplicationService.name);
|
||||
// return await fetchCursor(outBinds.P_ERRORMESG, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_ERRORMESG, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Updated Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -374,7 +406,14 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_ERRORMESG, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_ERRORMESG, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Updated Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -414,7 +453,110 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_ERRORMESG, CarnetApplicationService.name);
|
||||
// return await fetchCursor(outBinds.P_ERRORMESG, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_ERRORMESG, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Added Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
|
||||
async EditGenerallistItems(body: AddGenerallistItemsDTO) {
|
||||
let connection;
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const GLTABLE_INSTANCE = await this.oracleService.get_GL_TABLE_INSTANCE(body);
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETAPPLICATION_PKG.EditGenerallistItems(
|
||||
:P_HEADERID, :P_GLTABLE, :P_USERID, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_HEADERID: { val: body.P_HEADERID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_GLTABLE: { val: GLTABLE_INSTANCE, type: 'CARNETSYS.GLTABLE' },
|
||||
// P_GLTABLE: { val: GLTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT },
|
||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
// P_ERRORMESG: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||
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, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Updated Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
|
||||
async DeleteGenerallistItems(body: DeleteGenerallistItemsDTO) {
|
||||
let connection;
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const GLTABLE_INSTANCE = await this.oracleService.get_GL_TABLE_INSTANCE(body);
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETAPPLICATION_PKG.DeleteGenerallistItems(
|
||||
:P_HEADERID, :P_ITEMNO, :P_USERID, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_HEADERID: { val: body.P_HEADERID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_ITEMNO: { val: body.P_ITEMNO, type: oracledb.DB_TYPE_NUMBER },
|
||||
// P_GLTABLE: { val: GLTABLE_INSTANCE, type: 'CARNETSYS.GLTABLE' },
|
||||
// P_GLTABLE: { val: GLTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT },
|
||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
// P_ERRORMESG: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||
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, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Deleted Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -432,7 +574,7 @@ export class CarnetApplicationService {
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETAPPLICATION_PKG.AddCountries(
|
||||
:P_HEADERID, :P_USSETS, :P_COUNTRYTABLE, :P_USERID, :P_ERRORMESG
|
||||
:P_HEADERID, :P_USSETS, :P_COUNTRYTABLE, :P_USERID, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
@ -442,8 +584,8 @@ export class CarnetApplicationService {
|
||||
// P_COUNTRYTABLE: { val: COUNTRYTABLE_INSTANCE, type: 'CARNETSYS.GLTABLE' },
|
||||
// P_COUNTRYTABLE: { val: COUNTRYTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT },
|
||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ERRORMESG: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||
// P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
// P_ERRORMESG: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
@ -451,12 +593,19 @@ export class CarnetApplicationService {
|
||||
await connection.commit();
|
||||
|
||||
const outBinds = result.outBinds;
|
||||
if (!outBinds?.P_ERRORMESG) {
|
||||
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_ERRORMESG, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Added Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -471,16 +620,36 @@ export class CarnetApplicationService {
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETAPPLICATION_PKG.UpdateHolder(
|
||||
:P_HEADERID, :P_SHIPTOTYPE, :P_SHIPADDRID, :P_FORMOFSECURITY, :P_INSPROTECTION,
|
||||
:P_LDIPROTECTION, :P_DELIVERYTYPE, :P_DELIVERYMETHOD, :P_PAYMENTMETHOD,
|
||||
:P_CUSTCOURIERNO, :P_REFNO, :P_NOTES, :P_USERID, :P_ERRORMESG
|
||||
CARNETAPPLICATION_PKG.UpdateShippingDetails(
|
||||
:P_HEADERID,
|
||||
:P_SHIPTOTYPE,:P_SHIPCONTACTID,:P_SHIPNAME,
|
||||
:P_ADDRESS1,:P_ADDRESS2,:P_CITY,:P_STATE,:P_ZIP,:P_COUNTRY,
|
||||
:P_FIRSTNAME,:P_LASTNAME,:P_TITLE,:P_PHONENO,:P_MOBILENO,:P_FAXNO,:P_EMAILADDRESS,:P_MIDDLEINITIAL,
|
||||
:P_FORMOFSECURITY,:P_INSPROTECTION,:P_LDIPROTECTION,
|
||||
:P_DELIVERYTYPE,:P_DELIVERYMETHOD,:P_PAYMENTMETHOD,
|
||||
:P_CUSTCOURIERNO,:P_REFNO,:P_NOTES,:P_USERID,
|
||||
:P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_HEADERID: { val: body.P_HEADERID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_SHIPTOTYPE: { val: body.P_SHIPTOTYPE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_SHIPADDRID: { val: body.P_SHIPADDRID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_SHIPCONTACTID: { val: body.P_SHIPCONTACTID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_SHIPNAME: { val: body.P_SHIPNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ADDRESS1: { val: body.P_ADDRESS1, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ADDRESS2: { val: body.P_ADDRESS2, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CITY: { val: body.P_CITY, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_STATE: { val: body.P_STATE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ZIP: { val: body.P_ZIP, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_COUNTRY: { val: body.P_COUNTRY, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_FIRSTNAME: { val: body.P_FIRSTNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_LASTNAME: { val: body.P_LASTNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_TITLE: { val: body.P_TITLE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_PHONENO: { val: body.P_PHONENO, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_MOBILENO: { val: body.P_MOBILENO, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_FAXNO: { val: body.P_FAXNO, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_EMAILADDRESS: { val: body.P_EMAILADDRESS, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_MIDDLEINITIAL: { val: body.P_MIDDLEINITIAL, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_FORMOFSECURITY: { val: body.P_FORMOFSECURITY, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_INSPROTECTION: { val: body.P_INSPROTECTION, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_LDIPROTECTION: { val: body.P_LDIPROTECTION, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
@ -491,8 +660,7 @@ export class CarnetApplicationService {
|
||||
P_REFNO: { val: body.P_REFNO, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_NOTES: { val: body.P_NOTES, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ERRORMESG: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||
// P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
@ -500,12 +668,54 @@ export class CarnetApplicationService {
|
||||
await connection.commit();
|
||||
|
||||
const outBinds = result.outBinds;
|
||||
if (!outBinds?.P_ERRORMESG) {
|
||||
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_ERRORMESG, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Updated Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
|
||||
async EstimatedFees(body: GetCarnetControlCenterDTO) {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETAPPLICATION_PKG.EstimatedFees(
|
||||
:P_SPID, :P_USERID , :P_HEADERID, :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_HEADERID: { val: body.P_HEADERID, 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, CarnetApplicationService.name);
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -515,14 +725,14 @@ export class CarnetApplicationService {
|
||||
|
||||
// processing [ PROCESSINGCENTER_PKG ]
|
||||
|
||||
async ProcessOriginalCarnet(body: CarnetProcessingCenterDTO) {
|
||||
async ProcessCarnet(body: CarnetProcessingCenterDTO) {
|
||||
let connection;
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
PROCESSINGCENTER_PKG.ProcessOriginalCarnet(
|
||||
PROCESSINGCENTER_PKG.ProcessCarnet(
|
||||
:P_USERID, :P_HEADERID :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
@ -543,7 +753,14 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Processed Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -578,7 +795,14 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Updated Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -613,7 +837,14 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Voided Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -648,7 +879,14 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
return await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Duplicated Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
@ -683,6 +921,188 @@ export class CarnetApplicationService {
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Closed Successfully", ...fres[0] };
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
|
||||
// [ CARNETCONTROLCENTER_PKG ]
|
||||
|
||||
async GetHolderstoEdit(body: GetCarnetControlCenterDTO) {
|
||||
|
||||
let connection;
|
||||
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETCONTROLCENTER_PKG.GetHolderstoEdit(
|
||||
:P_SPID, :P_USERID , :P_HEADERID, :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_HEADERID: { val: body.P_HEADERID, 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, CarnetApplicationService.name);
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
|
||||
}
|
||||
async GetGoodsDetailstoEdit(body: GetCarnetControlCenterDTO) {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETCONTROLCENTER_PKG.GetGoodsDetailstoEdit(
|
||||
:P_SPID, :P_USERID , :P_HEADERID, :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_HEADERID: { val: body.P_HEADERID, 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, CarnetApplicationService.name);
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
async GetCountryDetailstoEdit(body: GetCarnetControlCenterDTO) {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETCONTROLCENTER_PKG.GetCountryDetailstoEdit(
|
||||
:P_SPID, :P_USERID , :P_HEADERID, :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_HEADERID: { val: body.P_HEADERID, 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, CarnetApplicationService.name);
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
async GetShipPaymentDetailstoEdit(body: GetCarnetControlCenterDTO) {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETCONTROLCENTER_PKG.GetShipPaymentDetailstoEdit(
|
||||
:P_SPID, :P_USERID , :P_HEADERID, :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_HEADERID: { val: body.P_HEADERID, 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, CarnetApplicationService.name);
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
async GetGoodsItemstoEdit(body: GetCarnetControlCenterDTO) {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
CARNETCONTROLCENTER_PKG.GetGoodsItemstoEdit(
|
||||
:P_SPID, :P_USERID , :P_HEADERID, :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_HEADERID: { val: body.P_HEADERID, 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, CarnetApplicationService.name);
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
|
||||
@ -120,7 +120,59 @@ export class HomePageService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return fres;
|
||||
// Step 1: Replace spaces in keys
|
||||
const mappedRows = fres.map((obj) => {
|
||||
const newObj = {};
|
||||
for (const key in obj) {
|
||||
const newKey = key.replace(/ /g, '_');
|
||||
newObj[newKey] = obj[key];
|
||||
}
|
||||
return newObj;
|
||||
});
|
||||
|
||||
// Step 2: Group and aggregate
|
||||
const reducedRows = mappedRows.reduce((acc, curr) => {
|
||||
let existing;
|
||||
|
||||
if (curr.Service_Provider_Name && curr.SPID) {
|
||||
existing = acc.find(
|
||||
(item) =>
|
||||
item.Service_Provider_Name === curr.Service_Provider_Name &&
|
||||
item.SPID === curr.SPID
|
||||
);
|
||||
} else if (curr.Preparer_Name && curr.CLIENTID) {
|
||||
existing = acc.find(
|
||||
(item) =>
|
||||
item.Preparer_Name === curr.Preparer_Name &&
|
||||
item.CLIENTID === curr.CLIENTID
|
||||
);
|
||||
}
|
||||
|
||||
if (existing) {
|
||||
existing.CARNETSTATUS.push(curr.CARNETSTATUS);
|
||||
existing.Carnet_Count.push(curr.Carnet_Count);
|
||||
} else {
|
||||
const newItem = {
|
||||
CARNETSTATUS: [curr.CARNETSTATUS],
|
||||
Carnet_Count: [curr.Carnet_Count],
|
||||
};
|
||||
|
||||
if (curr.Service_Provider_Name && curr.SPID) {
|
||||
newItem['Service_Provider_Name'] = curr.Service_Provider_Name;
|
||||
newItem['SPID'] = curr.SPID;
|
||||
} else if (curr.Preparer_Name && curr.CLIENTID) {
|
||||
newItem['Preparer_Name'] = curr.Preparer_Name;
|
||||
newItem['CLIENTID'] = curr.CLIENTID;
|
||||
}
|
||||
|
||||
acc.push(newItem);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
|
||||
return reducedRows;
|
||||
} catch (error) {
|
||||
handleError(error, HomePageService.name)
|
||||
} finally {
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
ClientContactControlsDTO,
|
||||
CreateClientContactsDTO, CreateClientDataDTO,
|
||||
CreateClientLocationsDTO,
|
||||
GetClientContactByLacationIdDTO,
|
||||
GetClientDTO,
|
||||
GetPreparersParamDTO, GetPreparersQueryDTO, UpdateClientContactsDTO, UpdateClientDTO, UpdateClientLocationsDTO
|
||||
} from 'src/dto/property.dto';
|
||||
@ -32,16 +33,19 @@ export class ManageClientsController {
|
||||
}
|
||||
|
||||
@Put('UpdateClientContacts')
|
||||
@Roles('ca','sa')
|
||||
UpdateClientContacts(@Body() body: UpdateClientContactsDTO) {
|
||||
return this.manageClientsService.UpdateClientContacts(body);
|
||||
}
|
||||
|
||||
@Put('UpdateClientLocations')
|
||||
@Roles('ca','sa')
|
||||
UpdateClientLocations(@Body() body: UpdateClientLocationsDTO) {
|
||||
return this.manageClientsService.UpdateClientLocations(body);
|
||||
}
|
||||
|
||||
@Post('CreateClientContacts')
|
||||
@Roles('ca','sa')
|
||||
CreateClientContact(@Body() body: CreateClientContactsDTO) {
|
||||
return this.manageClientsService.CreateClientContact(body);
|
||||
}
|
||||
@ -62,6 +66,7 @@ export class ManageClientsController {
|
||||
}
|
||||
|
||||
@Post('CreateClientLocations')
|
||||
@Roles('ca','sa')
|
||||
CreateClientLocation(@Body() body: CreateClientLocationsDTO) {
|
||||
return this.manageClientsService.CreateClientLocation(body);
|
||||
}
|
||||
@ -77,11 +82,19 @@ export class ManageClientsController {
|
||||
}
|
||||
|
||||
@Get('GetPreparerContactsByClientid/:P_SPID/:P_CLIENTID')
|
||||
@Roles('ca','sa')
|
||||
GetPreparerContactsByClientid(@Param() body: GetClientDTO) {
|
||||
return this.manageClientsService.GetPreparerContactsByClientid(body);
|
||||
}
|
||||
|
||||
@Get('GetPreparerContactsbyClientLocationID/:P_SPID/:P_LOCATIONID')
|
||||
@Roles('ca','sa')
|
||||
GetPreparerContactsbyClientLocationID(@Param() body: GetClientContactByLacationIdDTO) {
|
||||
return this.manageClientsService.GetPreparerContactsbyClientLocationID(body);
|
||||
}
|
||||
|
||||
@Get('GetPreparerLocByClientid/:P_SPID/:P_CLIENTID')
|
||||
@Roles('ca','sa')
|
||||
GetPreparerLocByClientid(@Param() body: GetClientDTO) {
|
||||
return this.manageClientsService.GetPreparerLocByClientid(body);
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
ClientContactControlsDTO,
|
||||
CreateClientContactsDTO, CreateClientDataDTO,
|
||||
CreateClientLocationsDTO,
|
||||
GetClientContactByLacationIdDTO,
|
||||
GetClientDTO,
|
||||
GetPreparersDTO, UpdateClientContactsDTO, UpdateClientDTO, UpdateClientLocationsDTO,
|
||||
} from 'src/dto/property.dto';
|
||||
@ -351,12 +352,12 @@ export class ManageClientsService {
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
MANAGEPREPARER_PKG.CreateClientContact(
|
||||
:P_SPID, :P_CLIENTID, :P_CONTACTSTABLE, :P_DEFCONTACTFLAG, :P_USERID, :P_CURSOR
|
||||
:P_SPID, :P_LOCATIONID, :P_CONTACTSTABLE, :P_DEFCONTACTFLAG, :P_USERID, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_SPID: { val: finalBody.P_SPID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_CLIENTID: { val: finalBody.P_CLIENTID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_LOCATIONID: { val: finalBody.P_LOCATIONID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_CONTACTSTABLE: { val: CONTACTSTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT },
|
||||
P_DEFCONTACTFLAG: { val: finalBody.P_DEFCONTACTFLAG, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
@ -718,6 +719,43 @@ export class ManageClientsService {
|
||||
}
|
||||
};
|
||||
|
||||
GetPreparerContactsbyClientLocationID = async (body: GetClientContactByLacationIdDTO) => {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
MANAGEPREPARER_PKG.GetPreparerContactsByClientid(
|
||||
:P_SPID, :P_LOCATIONID, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_LOCATIONID: { val: body.P_LOCATIONID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{
|
||||
outFormat: oracledb.OUT_FORMAT_OBJECT,
|
||||
},
|
||||
);
|
||||
|
||||
const outBinds: any = 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, ManageClientsService.name);
|
||||
|
||||
} catch (error) {
|
||||
handleError(error, ManageClientsService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, ManageClientsService.name)
|
||||
}
|
||||
}
|
||||
|
||||
GetPreparerLocByClientid = async (body: GetClientDTO) => {
|
||||
let connection;
|
||||
|
||||
|
||||
@ -8,15 +8,16 @@ import {
|
||||
Patch,
|
||||
Post,
|
||||
Put,
|
||||
Query,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
import { ApiQuery, ApiTags } from '@nestjs/swagger';
|
||||
import { ManageHoldersService } from './manage-holders.service';
|
||||
|
||||
import {
|
||||
CreateHolderContactsDTO,
|
||||
CreateHoldersDTO, GetHolderDTO, HolderActivateOrInactivateDTO,
|
||||
HolderContactActivateOrInactivateDTO, SearchHolderDTO, UpdateHolderContactDTO, UpdateHolderDTO
|
||||
HolderContactActivateOrInactivateDTO, SearchHolderDTO, SPID_DTO, UpdateHolderContactDTO, UpdateHolderDTO
|
||||
} from 'src/dto/property.dto';
|
||||
import { Roles } from 'src/decorators/roles.decorator';
|
||||
import { JwtAuthGuard } from 'src/guards/jwt-auth.guard';
|
||||
@ -29,16 +30,39 @@ import { RolesGuard } from 'src/guards/roles.guard';
|
||||
export class ManageHoldersController {
|
||||
constructor(private readonly manageHoldersService: ManageHoldersService) { }
|
||||
|
||||
@Get('SearchHolder/:P_SPID/:P_HOLDERNAME')
|
||||
SearchHolder(@Param() param: SearchHolderDTO) {
|
||||
return this.manageHoldersService.SearchHolder(param)
|
||||
@Get('SearchHolder/:P_SPID')
|
||||
@ApiQuery({ name: "P_HOLDERNAME", type: String, required: false, description: "Optional" })
|
||||
SearchHolder(
|
||||
@Param('P_SPID') P_SPID: number,
|
||||
@Query('P_HOLDERNAME') P_HOLDERNAME?: string | null | undefined,
|
||||
) {
|
||||
let rawHolderName: string | null | undefined = P_HOLDERNAME;
|
||||
|
||||
if (typeof rawHolderName === 'string') {
|
||||
rawHolderName = rawHolderName.trim();
|
||||
rawHolderName = rawHolderName.replace(/^['"]|['"]$/g, '');
|
||||
|
||||
if (rawHolderName === '' || rawHolderName.toLowerCase() === 'null') {
|
||||
rawHolderName = null;
|
||||
} else {
|
||||
const allowedPattern = /^[A-Za-z0-9 _@&.-]+$/;
|
||||
|
||||
// uncomment for strict validation
|
||||
|
||||
// if (!allowedPattern.test(rawHolderName)) {
|
||||
// rawHolderName = null;
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
rawHolderName = null;
|
||||
}
|
||||
const body = { P_SPID, P_HOLDERNAME: rawHolderName }
|
||||
return this.manageHoldersService.SearchHolder(body)
|
||||
}
|
||||
|
||||
@Post('/CreateHolderData')
|
||||
CreateHolders(@Body() body: CreateHoldersDTO) {
|
||||
return this.manageHoldersService.CreateHolders(body);
|
||||
// return this.manageHoldersService.CreateHoldersX();
|
||||
// return {message:"Request received.."}
|
||||
}
|
||||
|
||||
@Post('CreateHoldercontact')
|
||||
|
||||
@ -8,7 +8,7 @@ import { closeOracleDbConnection, fetchCursor, handleError, setEmptyStringsToNul
|
||||
import {
|
||||
CreateHolderContactsDTO,
|
||||
CreateHoldersDTO, GetHolderDTO, HolderActivateOrInactivateDTO,
|
||||
HolderContactActivateOrInactivateDTO, SearchHolderDTO, UpdateHolderContactDTO, UpdateHolderDTO
|
||||
HolderContactActivateOrInactivateDTO, SearchHolderDTO, SPID_DTO, UpdateHolderContactDTO, UpdateHolderDTO
|
||||
} from 'src/dto/property.dto';
|
||||
import { OracleService } from '../oracle.service';
|
||||
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||
@ -64,7 +64,7 @@ export class ManageHoldersService {
|
||||
:P_USCIBMEMBERFLAG, :P_GOVAGENCYFLAG, :P_HOLDERNAME, :P_NAMEQUALIFIER,
|
||||
:P_ADDLNAME, :P_ADDRESS1, :P_ADDRESS2, :P_CITY,
|
||||
:P_STATE, :P_ZIP, :P_COUNTRY, :P_USERID,
|
||||
:P_CONTACTSTABLE, :P_HOLDERCURSOR, :P_HOLDERCONTACTCURSOR
|
||||
:P_HOLDERCURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
@ -86,7 +86,7 @@ export class ManageHoldersService {
|
||||
P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
// P_CONTACTSTABLE: { val: CONTACTSTABLE_INSTANCE, type: oracledb.DB_TYPE_OBJECT },
|
||||
P_HOLDERCURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT },
|
||||
P_HOLDERCONTACTCURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
// P_HOLDERCONTACTCURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
@ -94,7 +94,7 @@ export class ManageHoldersService {
|
||||
await connection.commit();
|
||||
|
||||
const outBinds: any = result.outBinds;
|
||||
if (!outBinds?.P_HOLDERCURSOR || !outBinds?.P_HOLDERCONTACTCURSOR) {
|
||||
if (!outBinds?.P_HOLDERCURSOR) {
|
||||
this.logger.error('One or more expected cursors are missing from stored procedure output.');
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
@ -103,19 +103,21 @@ export class ManageHoldersService {
|
||||
// throw new InternalServerException("Incomplete data received from the database.");
|
||||
// }
|
||||
|
||||
// const fres: any = await fetchCursor(outBinds.P_CURSOR, ParamTableService.name);
|
||||
const fres: any = await fetchCursor(outBinds.P_HOLDERCURSOR, ManageHoldersService.name);
|
||||
|
||||
// if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
// this.logger.warn(fres[0].ERRORMESG);
|
||||
// throw new BadRequestException(fres[0].ERRORMESG)
|
||||
// }
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
// return {
|
||||
// holderDetails: await fetchCursor(outBinds.P_HOLDERCURSOR, ManageHoldersService.name),
|
||||
// holderContactDetails: await fetchCursor(outBinds.P_HOLDERCONTACTCURSOR, ManageHoldersService.name),
|
||||
// }
|
||||
|
||||
return await fetchCursor(outBinds.P_HOLDERCURSOR, ManageHoldersService.name);
|
||||
// return await fetchCursor(outBinds.P_HOLDERCURSOR, ManageHoldersService.name);
|
||||
|
||||
return { statusCode: 201, message: "Created Successfully", ...fres[0] };
|
||||
|
||||
} catch (error) {
|
||||
handleError(error, ManageHoldersService.name)
|
||||
@ -149,7 +151,7 @@ export class ManageHoldersService {
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
MANAGEPREPARER_PKG.CreateClientContact(
|
||||
MANAGEHOLDER_PKG.CreateHoldercontact(
|
||||
:P_SPID, :P_HOLDERID, :P_CONTACTSTABLE, :P_USERID, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
@ -221,7 +223,7 @@ export class ManageHoldersService {
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
MANAGEHOLDER_PKG.UPDATEHOLDERS(
|
||||
MANAGEHOLDER_PKG.UPDATEHOLDER(
|
||||
:P_HOLDERID, :P_SPID, :P_LOCATIONID, :P_HOLDERNO,
|
||||
:P_HOLDERTYPE, :P_USCIBMEMBERFLAG, :P_GOVAGENCYFLAG, :P_HOLDERNAME,
|
||||
:P_NAMEQUALIFIER, :P_ADDLNAME, :P_ADDRESS1, :P_ADDRESS2,
|
||||
@ -230,24 +232,24 @@ export class ManageHoldersService {
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_HOLDERID: { VAL: finalBody.P_HOLDERID, TYPE: oracledb.DB_TYPE_NUMBER },
|
||||
P_SPID: { VAL: finalBody.P_SPID, TYPE: oracledb.DB_TYPE_NUMBER },
|
||||
P_LOCATIONID: { VAL: finalBody.P_LOCATIONID, TYPE: oracledb.DB_TYPE_NUMBER },
|
||||
P_HOLDERNO: { VAL: finalBody.P_HOLDERNO, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_HOLDERTYPE: { VAL: finalBody.P_HOLDERTYPE, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_USCIBMEMBERFLAG: { VAL: finalBody.P_USCIBMEMBERFLAG, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_GOVAGENCYFLAG: { VAL: finalBody.P_GOVAGENCYFLAG, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_HOLDERNAME: { VAL: finalBody.P_HOLDERNAME, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_NAMEQUALIFIER: { VAL: finalBody.P_NAMEQUALIFIER, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ADDLNAME: { VAL: finalBody.P_ADDLNAME, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ADDRESS1: { VAL: finalBody.P_ADDRESS1, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ADDRESS2: { VAL: finalBody.P_ADDRESS2, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CITY: { VAL: finalBody.P_CITY, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_STATE: { VAL: finalBody.P_STATE, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ZIP: { VAL: finalBody.P_ZIP, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_COUNTRY: { VAL: finalBody.P_COUNTRY, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_USERID: { VAL: finalBody.P_USERID, TYPE: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CURSOR: { TYPE: oracledb.CURSOR, DIR: oracledb.BIND_OUT }
|
||||
P_HOLDERID: { val: finalBody.P_HOLDERID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_SPID: { val: finalBody.P_SPID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_LOCATIONID: { val: finalBody.P_LOCATIONID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_HOLDERNO: { val: finalBody.P_HOLDERNO, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_HOLDERTYPE: { val: finalBody.P_HOLDERTYPE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_USCIBMEMBERFLAG: { val: finalBody.P_USCIBMEMBERFLAG, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_GOVAGENCYFLAG: { val: finalBody.P_GOVAGENCYFLAG, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_HOLDERNAME: { val: finalBody.P_HOLDERNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_NAMEQUALIFIER: { val: finalBody.P_NAMEQUALIFIER, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ADDLNAME: { val: finalBody.P_ADDLNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ADDRESS1: { val: finalBody.P_ADDRESS1, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ADDRESS2: { val: finalBody.P_ADDRESS2, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CITY: { val: finalBody.P_CITY, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_STATE: { val: finalBody.P_STATE, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ZIP: { val: finalBody.P_ZIP, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_COUNTRY: { val: finalBody.P_COUNTRY, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_USERID: { val: finalBody.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{
|
||||
outFormat: oracledb.OUT_FORMAT_OBJECT,
|
||||
@ -268,8 +270,7 @@ export class ManageHoldersService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
|
||||
return { P_cursor: fres };
|
||||
return { statusCode: 200, message: "Updated Successfully", ...fres[0] };
|
||||
|
||||
// return fres
|
||||
} catch (error) {
|
||||
@ -292,9 +293,9 @@ export class ManageHoldersService {
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_SPID: { VAL: body.P_SPID, TYPE: oracledb.DB_TYPE_NUMBER },
|
||||
P_HOLDERID: { VAL: body.P_HOLDERID, TYPE: oracledb.DB_TYPE_NUMBER },
|
||||
P_CURSOR: { TYPE: oracledb.CURSOR, DIR: oracledb.BIND_OUT }
|
||||
P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_HOLDERID: { val: body.P_HOLDERID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{
|
||||
outFormat: oracledb.OUT_FORMAT_OBJECT,
|
||||
@ -302,6 +303,7 @@ export class ManageHoldersService {
|
||||
);
|
||||
|
||||
const outBinds: any = 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.");
|
||||
@ -314,7 +316,7 @@ export class ManageHoldersService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { P_CURSOR: fres };
|
||||
return fres.length > 0 ? fres[0] : fres;
|
||||
} catch (error) {
|
||||
handleError(error, ManageHoldersService.name)
|
||||
} finally {
|
||||
@ -350,7 +352,7 @@ export class ManageHoldersService {
|
||||
|
||||
const result: Result<any> = await connection.execute(
|
||||
`BEGIN
|
||||
MANAGEHOLDER_PKG.UPDATEHOLDERS(
|
||||
MANAGEHOLDER_PKG.UpdateHolderContacts(
|
||||
:P_HOLDERCONTACTID, :P_SPID, :P_FIRSTNAME, :P_LASTNAME,
|
||||
:P_MIDDLEINITIAL, :P_TITLE, :P_PHONENO, :P_MOBILENO,
|
||||
:P_FAXNO, :P_EMAILADDRESS, :P_USERID, :P_CURSOR
|
||||
@ -392,7 +394,7 @@ export class ManageHoldersService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { P_cursor: fres };
|
||||
return { statusCode: 200, message: "Updated Successfully", ...fres[0] };
|
||||
|
||||
// return fres
|
||||
} catch (error) {
|
||||
@ -437,7 +439,7 @@ export class ManageHoldersService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { P_CURSOR: fres };
|
||||
return fres;
|
||||
} catch (error) {
|
||||
handleError(error, ManageHoldersService.name)
|
||||
} finally {
|
||||
@ -483,7 +485,7 @@ export class ManageHoldersService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { P_CURSOR: fres };
|
||||
return { statusCode: 200, message: 'Inactivated holder successfully' };
|
||||
} catch (error) {
|
||||
handleError(error, ManageHoldersService.name)
|
||||
} finally {
|
||||
@ -529,7 +531,7 @@ export class ManageHoldersService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { P_CURSOR: fres };
|
||||
return { statusCode: 200, message: 'Reactivated holder successfully' };
|
||||
} catch (error) {
|
||||
handleError(error, ManageHoldersService.name)
|
||||
} finally {
|
||||
@ -575,7 +577,7 @@ export class ManageHoldersService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { P_CURSOR: fres };
|
||||
return { statusCode: 200, message: 'Inactivated holder contact successfully' };
|
||||
} catch (error) {
|
||||
handleError(error, ManageHoldersService.name)
|
||||
} finally {
|
||||
@ -621,7 +623,7 @@ export class ManageHoldersService {
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { P_CURSOR: fres };
|
||||
return { statusCode: 200, message: 'Reactivated holder contact successfully' };
|
||||
} catch (error) {
|
||||
handleError(error, ManageHoldersService.name)
|
||||
} finally {
|
||||
@ -629,7 +631,7 @@ export class ManageHoldersService {
|
||||
}
|
||||
};
|
||||
|
||||
SearchHolder = async (body: SearchHolderDTO) => {
|
||||
SearchHolder = async (body: { P_SPID: number, P_HOLDERNAME: string | null }) => {
|
||||
let connection;
|
||||
|
||||
try {
|
||||
@ -643,7 +645,7 @@ export class ManageHoldersService {
|
||||
END;`,
|
||||
{
|
||||
P_SPID: { val: body.P_SPID, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_HOLDERCONTACTID: { val: body.P_HOLDERNAME, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_HOLDERNAME: { val: body.P_HOLDERNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{
|
||||
|
||||
@ -26,6 +26,6 @@ import { AuthModule } from 'src/auth/auth.module';
|
||||
],
|
||||
providers: [OracleService],
|
||||
controllers: [],
|
||||
exports: [OracleService],
|
||||
exports: [OracleService, UserMaintenanceModule],
|
||||
})
|
||||
export class OracleModule {}
|
||||
|
||||
@ -36,8 +36,12 @@ export class ParamTableController {
|
||||
return this.paramTableService.GETPARAMVALUES(body);
|
||||
}
|
||||
|
||||
@Get('GetCountriesAndMessages')
|
||||
GET_COUNTRIES_AND_MESSAGES() {
|
||||
return this.GET_COUNTRIES_AND_MESSAGES();
|
||||
}
|
||||
|
||||
@Post('/CreateTableRecord')
|
||||
@Roles('ua')
|
||||
createTableRecord(@Body() body: CreateTableRecordDTO) {
|
||||
return this.paramTableService.CREATETABLERECORD(body);
|
||||
}
|
||||
|
||||
@ -63,6 +63,38 @@ export class ParamTableService {
|
||||
}
|
||||
}
|
||||
|
||||
async GET_COUNTRIES_AND_MESSAGES() {
|
||||
let connection;
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
MANAGEPARAMTABLE_PKG.GetCountriesAndMessages(:P_CURSOR);
|
||||
END;`,
|
||||
{
|
||||
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, ParamTableService.name);
|
||||
|
||||
} catch (error) {
|
||||
handleError(error, ParamTableService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, ParamTableService.name)
|
||||
}
|
||||
}
|
||||
|
||||
async CREATETABLERECORD(body: CreateTableRecordDTO) {
|
||||
|
||||
let connection;
|
||||
|
||||
@ -6,6 +6,7 @@ import { AuthModule } from 'src/auth/auth.module';
|
||||
@Module({
|
||||
imports: [AuthModule],
|
||||
controllers: [UserMaintenanceController],
|
||||
providers: [UserMaintenanceService]
|
||||
providers: [UserMaintenanceService],
|
||||
exports: [UserMaintenanceService]
|
||||
})
|
||||
export class UserMaintenanceModule { }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user