Skip to content

Commit

Permalink
Merge pull request #166 from Sourav-Tekdi/getUserIdFromToken
Browse files Browse the repository at this point in the history
Storing Logged-in User ID in Create & Update Operations
  • Loading branch information
Shubham4026 authored Feb 26, 2025
2 parents 9251512 + 5d6f17e commit f54c1a3
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 27 deletions.
1 change: 0 additions & 1 deletion src/adapters/postgres/cohort-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ConsoleLogger, HttpStatus, Injectable } from "@nestjs/common";
import jwt_decode from "jwt-decode";
import { ReturnResponseBody } from "src/cohort/dto/cohort.dto";
import { CohortSearchDto } from "src/cohort/dto/cohort-search.dto";
import { CohortCreateDto } from "src/cohort/dto/cohort-create.dto";
Expand Down
5 changes: 0 additions & 5 deletions src/adapters/postgres/cohortAcademicYear-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { HttpStatus, Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { CohortAcademicYear } from "src/cohortAcademicYear/entities/cohortAcademicYear.entity";
import { Repository } from "typeorm";
import jwt_decode from "jwt-decode";
import { IServiceLocatorCohortAcademicYear } from "../cohortacademicyearservicelocator";
import { Request, Response } from "express";
import { CohortAcademicYearDto } from "src/cohortAcademicYear/dto/cohort-academicyear.dto";
Expand All @@ -26,10 +25,6 @@ export class CohortAcademicYearService implements IServiceLocatorCohortAcademicY
async createCohortAcademicYear(tenantId: string, request: Request, cohortAcademicYearDto: CohortAcademicYearDto, response: Response) {
const apiId = APIID.ADD_COHORT_TO_ACADEMIC_YEAR;
try {
const decoded: any = jwt_decode(request.headers.authorization);
cohortAcademicYearDto.createdBy = decoded?.sub;
cohortAcademicYearDto.updatedBy = decoded?.sub;

const existingCohort = await this.cohortRepository.findOne({
where: { cohortId: cohortAcademicYearDto.cohortId, status: 'active' },
});
Expand Down
2 changes: 0 additions & 2 deletions src/adapters/postgres/rbac/assignrole-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { UserRoleMapping } from "src/rbac/assign-role/entities/assign-role.entit
import { Role } from "src/rbac/role/entities/role.entity";
import { IsAlpha, IsUUID, isUUID } from "class-validator";
import { executionAsyncResource } from "async_hooks";
import jwt_decode from "jwt-decode";
import { DeleteAssignRoleDto } from "src/rbac/assign-role/dto/delete-assign-role.dto";
import { Response } from "express";
import { APIID } from "src/common/utils/api-id.config";
Expand All @@ -37,7 +36,6 @@ export class PostgresAssignroleService {
) {
const apiId = APIID.USERROLE_CREATE;
try {
// const decoded: any = jwt_decode(request.headers.authorization);
const userId = createAssignRoleDto.userId;
const roles = createAssignRoleDto.roleId;
const tenantId = createAssignRoleDto.tenantId;
Expand Down
9 changes: 5 additions & 4 deletions src/cohort/cohort.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { APIID } from "src/common/utils/api-id.config";
import { isUUID } from "class-validator";
import { API_RESPONSES } from "@utils/response.messages";
import { LoggerUtil } from "src/common/logger/LoggerUtil";
import { GetUserId } from "src/common/decorators/getUserId.decorator";

@ApiTags("Cohort")
@Controller("cohort")
Expand Down Expand Up @@ -114,8 +115,8 @@ export class CohortController {
@Body() cohortCreateDto: CohortCreateDto,
@UploadedFile() image,
@Res() response: Response,
@Query("userId") userId: string | null = null
) {
@GetUserId("userId", ParseUUIDPipe) userId: string ) {
const tenantId = headers["tenantid"];
const academicYearId = headers["academicyearid"];
if (!tenantId || !isUUID(tenantId)) {
Expand Down Expand Up @@ -193,7 +194,7 @@ export class CohortController {
@Body() cohortUpdateDto: CohortUpdateDto,
@UploadedFile() image,
@Res() response: Response,
@Query("userId") userId: string
@GetUserId("userId", ParseUUIDPipe) userId: string
) {
cohortUpdateDto.updatedBy = userId;
return await this.cohortAdapter
Expand All @@ -209,7 +210,7 @@ export class CohortController {
public async updateCohortStatus(
@Param("cohortId") cohortId: string,
@Res() response: Response,
@Query("userId") userId: string
@GetUserId("userId", ParseUUIDPipe) userId: string
) {
return await this.cohortAdapter
.buildCohortAdapter()
Expand Down
8 changes: 6 additions & 2 deletions src/cohortAcademicYear/cohortAcademicYear.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import {
Controller, Headers, Post, UseFilters, UsePipes, Req,
Res, ValidationPipe,
BadRequestException,
Body
Body,
ParseUUIDPipe
} from '@nestjs/common';
import { ApiBadRequestResponse, ApiBasicAuth, ApiBody, ApiCreatedResponse, ApiHeader, ApiInternalServerErrorResponse, ApiTags } from '@nestjs/swagger';
import { APIID } from '@utils/api-id.config';
Expand All @@ -12,6 +13,7 @@ import { Response, Request } from 'express';
import { AllExceptionsFilter } from 'src/common/filters/exception.filter';
import { CohortAcademicYearDto } from './dto/cohort-academicyear.dto';
import { CohortAcademicYearAdapter } from './cohortacademicyearsadaptor';
import { GetUserId } from 'src/common/decorators/getUserId.decorator';

@ApiTags("CohortAcademicYear")
@Controller('cohort-academic-year')
Expand All @@ -34,12 +36,14 @@ export class CohortAcademicYearController {
@Headers() headers,
@Req() request: Request,
@Body() cohortAcademicYearDto: CohortAcademicYearDto,
@Res() response: Response
@Res() response: Response,
@GetUserId("userId", ParseUUIDPipe) userId: string,
) {
let tenantId = headers["tenantid"];
if (tenantId && !isUUID(tenantId)) {
throw new BadRequestException(API_RESPONSES.TENANTID_VALIDATION);
}
cohortAcademicYearDto.createdBy = userId;
return this.cohortAcademicYearAdapter.buildAcademicYears().createCohortAcademicYear(tenantId, request, cohortAcademicYearDto, response);
}
}
8 changes: 5 additions & 3 deletions src/cohortMembers/cohortMembers.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
Query,
UseFilters,
BadRequestException,
ParseUUIDPipe,
} from "@nestjs/common";
import { CohortMembersSearchDto } from "./dto/cohortMembers-search.dto";
import { Request } from "@nestjs/common";
Expand All @@ -41,10 +42,11 @@ import { APIID } from "src/common/utils/api-id.config";
import { BulkCohortMember } from "./dto/bulkMember-create.dto";
import { isUUID } from "class-validator";
import { API_RESPONSES } from "@utils/response.messages";
import { GetUserId } from "src/common/decorators/getUserId.decorator";

@ApiTags("Cohort Member")
@Controller("cohortmember")
// @UseGuards(JwtAuthGuard)
@UseGuards(JwtAuthGuard)
export class CohortMembersController {
constructor(private readonly cohortMemberAdapter: CohortMembersAdapter) { }

Expand All @@ -69,7 +71,7 @@ export class CohortMembersController {
public async createCohortMembers(
@Headers() headers,
@Req() request,
@Query('userId') userId: string,
@GetUserId("userId", ParseUUIDPipe) userId: string,
@Body() cohortMembersDto: CohortMembersDto,
@Res() response: Response
) {
Expand Down Expand Up @@ -263,7 +265,7 @@ export class CohortMembersController {
@Headers() headers,
@Req() request,
@Body() bulkCohortMembersDto: BulkCohortMember,
@Query('userId') userId: string, // Now using userId from query
@GetUserId("userId", ParseUUIDPipe) userId: string, // Now using userId from query
@Res() response: Response
) {
const loginUser = userId;
Expand Down
21 changes: 21 additions & 0 deletions src/common/decorators/getUserId.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createParamDecorator, ExecutionContext, UnauthorizedException } from '@nestjs/common';
import jwt_decode from 'jwt-decode';

export const GetUserId = createParamDecorator(
(data: unknown, ctx: ExecutionContext): string => {
const request = ctx.switchToHttp().getRequest();
const authHeader = request.headers.authorization;

if (!authHeader || !authHeader.startsWith('Bearer ')) {
throw new UnauthorizedException('Invalid or missing token');
}

try {
const token = authHeader.split(' ')[1]; // Extract JWT token
const decoded: any = jwt_decode(token); // Decode token
return decoded?.sub; // Assuming `sub` is where userId is stored
} catch (error) {
throw new UnauthorizedException('Invalid token');
}
},
);
1 change: 0 additions & 1 deletion src/fields/fields.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { FieldsDto } from "src/fields/dto/fields.dto";
import { FieldsSearchDto } from "src/fields/dto/fields-search.dto";
import { FieldValuesDto } from "src/fields/dto/field-values.dto";
import { FieldValuesSearchDto } from "src/fields/dto/field-values-search.dto";
import jwt_decode from "jwt-decode";
import { ErrorResponse } from "src/error-response";
import { Fields } from "./entities/fields.entity";
import { FieldValues } from "./entities/fields-values.entity";
Expand Down
7 changes: 6 additions & 1 deletion src/forms/forms.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
SerializeOptions,
UseFilters, UsePipes,
ValidationPipe,
ParseUUIDPipe,
} from "@nestjs/common";
import { FormsService } from "./forms.service";
import {
Expand All @@ -21,6 +22,7 @@ import { FormCreateDto } from './dto/form-create.dto';
import { APIID } from '@utils/api-id.config';
import { isUUID } from 'class-validator';
import { API_RESPONSES } from '@utils/response.messages';
import { GetUserId } from "src/common/decorators/getUserId.decorator";

@Controller("form")
@ApiTags("Forms")
Expand Down Expand Up @@ -68,9 +70,12 @@ export class FormsController {
@Headers() headers,
@Req() request: Request,
@Body() formCreateDto: FormCreateDto,
@Res() response: Response
@Res() response: Response,
@GetUserId("userId", ParseUUIDPipe) userId: string,
) {
let tenantId = headers["tenantid"];
formCreateDto.createdBy = userId;

if (tenantId && !isUUID(tenantId)) {
throw new BadRequestException(API_RESPONSES.TENANTID_VALIDATION);
}
Expand Down
4 changes: 0 additions & 4 deletions src/forms/forms.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,6 @@ export class FormsService {
let apiId = APIID.FORM_CREATE;

try {
const decoded: any = jwt_decode(request.headers.authorization);
formCreateDto.createdBy = decoded?.sub;
formCreateDto.updatedBy = decoded?.sub;

formCreateDto.contextType = formCreateDto.contextType.toUpperCase();
formCreateDto.context = formCreateDto.context.toUpperCase();
formCreateDto.title = formCreateDto.title.toUpperCase();
Expand Down
7 changes: 4 additions & 3 deletions src/tenant/tenant.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Request, Response } from "express";
import { TenantSearchDTO } from './dto/tenant-search.dto';
import { API_RESPONSES } from '@utils/response.messages';
import { isUUID } from 'class-validator';
import { GetUserId } from 'src/common/decorators/getUserId.decorator';

@ApiTags("Tenant")
@Controller('tenant')
Expand Down Expand Up @@ -56,7 +57,7 @@ export class TenantController {
@Res() response: Response,
@Body() tenantCreateDto: TenantCreateDto,
@UploadedFiles() files: Express.Multer.File[],
@Query("userId", new ParseUUIDPipe()) userId: string
@GetUserId("userId", ParseUUIDPipe) userId: string
): Promise<Response> {
const uploadedFiles = [];

Expand Down Expand Up @@ -84,7 +85,7 @@ export class TenantController {
@Param("id", new ParseUUIDPipe()) id: string,
@Body() tenantUpdateDto: TenantUpdateDto,
@UploadedFiles() files: Express.Multer.File[],
@Query("userId", new ParseUUIDPipe()) userId: string,
@GetUserId("userId", ParseUUIDPipe) userId: string,
): Promise<Response> {
const tenantId = id;
const uploadedFiles = [];
Expand Down Expand Up @@ -115,7 +116,7 @@ export class TenantController {
@Req() request: Request,
@Res() response: Response,
@Param("id", new ParseUUIDPipe()) id: string,
@Query("userId", new ParseUUIDPipe()) userId: string,
@GetUserId("userId", ParseUUIDPipe) userId: string,
) {
const tenantId = id;
return await this.tenantService.deleteTenants(request, tenantId, response);
Expand Down
4 changes: 3 additions & 1 deletion src/user/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { API_RESPONSES } from "@utils/response.messages";
import { LoggerUtil } from "src/common/logger/LoggerUtil";
import { OtpSendDTO } from "./dto/otpSend.dto";
import { OtpVerifyDTO } from "./dto/otpVerify.dto";
import { GetUserId } from "src/common/decorators/getUserId.decorator";
export interface UserData {
context: string;
tenantId: string;
Expand Down Expand Up @@ -154,10 +155,11 @@ export class UserController {
public async updateUser(
@Headers() headers,
@Param("userid") userId: string,
@GetUserId("loginUserId", ParseUUIDPipe) loginUserId: string,
@Body() userUpdateDto: UserUpdateDTO,
@Res() response: Response
) {
// userDto.tenantId = headers["tenantid"];
userUpdateDto.userData.updatedBy = loginUserId;
userUpdateDto.userId = userId;
return await this.userAdapter
.buildUserAdapter()
Expand Down

0 comments on commit f54c1a3

Please sign in to comment.