register mod

This commit is contained in:
Kallesh B S 2025-07-10 17:06:39 +05:30
parent 0cd9b8ca85
commit cfb09b1f16
3 changed files with 105 additions and 39 deletions

View File

@ -3,7 +3,7 @@ import { OracleDBService } from 'src/db/db.service';
import { AuthLoginDTO, MailTemplateDTO, MailTypeDTO, SendMailDTO } from './auth.dto'; import { AuthLoginDTO, MailTemplateDTO, MailTypeDTO, SendMailDTO } from './auth.dto';
import * as oracledb from 'oracledb'; import * as oracledb from 'oracledb';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import axios, { AxiosRequestConfig } from 'axios'; import axios, { AxiosError, AxiosRequestConfig } from 'axios';
import { Request } from 'express'; import { Request } from 'express';
import * as jwkToPem from "jwk-to-pem" import * as jwkToPem from "jwk-to-pem"
import * as jwt from "jsonwebtoken" import * as jwt from "jsonwebtoken"
@ -394,7 +394,7 @@ export class AuthService {
let adminAccessToken = await this.getAdminAccessToken(); let adminAccessToken = await this.getAdminAccessToken();
console.log(`${this.USERS_URL}/${userDetails.id}/reset-password`); // console.log(`${this.USERS_URL}/${userDetails.id}/reset-password`);
const options2: AxiosRequestConfig = { const options2: AxiosRequestConfig = {
@ -465,9 +465,9 @@ export class AuthService {
// throw new BadRequestException(); // throw new BadRequestException();
// } // }
const response: any = await this.userMaintenanceService.ValidateEmail({ P_EMAILADDR: body.P_EMAILADDR }) const emailVerifyResponse: any = await this.userMaintenanceService.ValidateEmail({ P_EMAILADDR: body.P_EMAILADDR })
if (Array.isArray(response) && response[0].ERRORMESG) { if (Array.isArray(emailVerifyResponse) && emailVerifyResponse[0].ERRORMESG) {
throw new BadRequestException(); throw new BadRequestException();
} }
@ -490,7 +490,7 @@ export class AuthService {
], ],
}; };
console.log(userPayload); // console.log(userPayload);
const adminAccessToken = await this.getAdminAccessToken(); const adminAccessToken = await this.getAdminAccessToken();
@ -504,19 +504,26 @@ export class AuthService {
if (response.status === 201) { if (response.status === 201) {
// console.log("Assigning role : ");
// console.log("checking validate email response : ", response);
const uid = await this.getUserIdByEmail(body.P_EMAILADDR); const uid = await this.getUserIdByEmail(body.P_EMAILADDR);
let ROLE = ""; let ROLE = "";
if (Array.isArray(response) && !response[0].ERRORMESG) { if (Array.isArray(emailVerifyResponse) && !emailVerifyResponse[0].ERRORMESG) {
switch (response[0].SOURCE) { switch (emailVerifyResponse[0].SOURCE) {
case "USCIB": ROLE = 'ua'; break; case "USCIB": ROLE = 'ua'; break;
case "SP": ROLE = 'sa'; break; case "SP": ROLE = 'sa'; break;
case "CLIENT": ROLE = 'ca'; break; case "CLIENT": ROLE = 'ca'; break;
} }
} }
// console.log("Role to assign : ", ROLE);
if (!ROLE) { if (!ROLE) {
console.log("ERROR while giving access : "); console.log("ERROR while giving access : ");
@ -525,6 +532,8 @@ export class AuthService {
const res = await this.assignRoleToUser(uid, ROLE); const res = await this.assignRoleToUser(uid, ROLE);
console.log("Assigning Role sussessfully ");
console.log(res); console.log(res);
return { statusCode: 201, message: 'User registered successfully' }; return { statusCode: 201, message: 'User registered successfully' };
@ -545,6 +554,46 @@ export class AuthService {
} }
} }
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> { async logoutUser(refreshToken: string): Promise<any> {
const url = `${this.KEYCLOAK_BASE_URL}/logout`; const url = `${this.KEYCLOAK_BASE_URL}/logout`;
@ -627,39 +676,7 @@ 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) { async getTokenFromRefreshToken(req: Request) {

View 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. Tokens cleared.',
});
}
// If not a match, fallback to default response
return response.status(status).json({
statusCode: status,
message,
});
}
}

View File

@ -8,6 +8,7 @@ import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { SwaggerDocumentOptions } from '@nestjs/swagger'; import { SwaggerDocumentOptions } from '@nestjs/swagger';
import { BadRequestException } from './exceptions/badRequest.exception'; import { BadRequestException } from './exceptions/badRequest.exception';
import * as cookieParser from 'cookie-parser'; import * as cookieParser from 'cookie-parser';
import { AuthExceptionFilter } from './filters/auth-exception.filter';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule, { const app = await NestFactory.create(AppModule, {
@ -30,6 +31,8 @@ async function bootstrap() {
app.use(cookieParser()); app.use(cookieParser());
app.useGlobalFilters(new AuthExceptionFilter());
function extractConstraints(validationErrors: ValidationError[]) { function extractConstraints(validationErrors: ValidationError[]) {
const constraints: { [key: string]: string }[] = []; const constraints: { [key: string]: string }[] = [];