Skip to content

Commit

Permalink
Merge pull request #98 from Real-Dev-Squad/fix/authorization
Browse files Browse the repository at this point in the history
Fix/authorization
  • Loading branch information
harshith-venkatesh authored Jul 29, 2023
2 parents a937c03 + e40ff97 commit c866309
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 10 deletions.
73 changes: 73 additions & 0 deletions middlewares/authorize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import Boom from '@hapi/boom';
import { NextFunction, Request, Response } from 'express';
import { findCalendarWithId, findEventWithId } from '../services/eventsService';

/**
* Middleware to authorize if the calendar belongs to the user
*
* @param req {Object} - Express request object
* @param res {Object} - Express response object
* @param next {Function} - Express middleware function
* @return {Object} - Returns unauthenticated object if token is invalid
*/
const calendarBelongsToUser = async (
req: Request,
res: Response,
next: NextFunction
): Promise<any | Response> => {
try {
const userId = req.userData.id;
const calendarId = +(req.params.calendarId || req.body.calendarId);

const calendarData = await findCalendarWithId(calendarId);

if (calendarData === null) {
logger.error('Calendar not found.');
return res.boom(Boom.notFound('Calendar not found'));
}

if (calendarData.ownerId !== userId) {
logger.info('Calendar does not belong to user');
return res.boom(Boom.forbidden('Calendar does not belong to user'));
}

return next();
} catch (err: any) {
logger.error('An internal server error occurred', { err: err.stack });
return res.boom(
Boom.badImplementation('An internal server error occurred')
);
}
};

const eventBelongsToUser = async (
req: Request,
res: Response,
next: NextFunction
): Promise<any | Response> => {
try {
const { eventId } = req.params;
const userId = req.userData.id;

const eventData = await findEventWithId(+eventId);

if (eventData === null) {
logger.info('Event not found');
return res.boom(Boom.notFound());
}

if (eventData.ownerId !== userId) {
logger.info('Event does not belong to user');
return res.boom(Boom.forbidden('Event does not belong to user'));
}

return next();
} catch (err: any) {
logger.error('An internal server error occurred', { err: err.stack });
return res.boom(
Boom.badImplementation('An internal server error occurred')
);
}
};

export { calendarBelongsToUser, eventBelongsToUser };
29 changes: 26 additions & 3 deletions routes/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,40 @@ import {
postEventSchema,
patchEventSchema,
} from '../middlewares/validators/zod-schemas/events';
import {
calendarBelongsToUser,
eventBelongsToUser,
} from '../middlewares/authorize';

const router = Router();

/* eslint-disable @typescript-eslint/no-misused-promises */
router.post('/', authenticate, validate(postEventSchema), postEvent);
router.patch('/:eventId', authenticate, validate(patchEventSchema), patchEvent);
router.get('/:eventId', authenticate, validate(getEventSchema), getEvents);
router.post(
'/',
authenticate,
validate(postEventSchema),
calendarBelongsToUser,
postEvent
);
router.patch(
'/:eventId',
authenticate,
validate(patchEventSchema),
eventBelongsToUser,
patchEvent
);
router.get(
'/:eventId',
authenticate,
validate(getEventSchema),
eventBelongsToUser,
getEvents
);
router.get(
'/calendar/:calendarId',
authenticate,
validate(getCalenderEventSchema),
calendarBelongsToUser,
getCalendarEvents
);
/* eslint-disable @typescript-eslint/no-misused-promises */
Expand Down
12 changes: 7 additions & 5 deletions server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import app from './app';
import { version } from './package.json';
import ErrnoException = NodeJS.ErrnoException;
import checkDatabaseConnection from './utils/prisma';
import { env } from 'process';

// Initialise globals
global.config = config;
Expand All @@ -27,11 +28,12 @@ server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
* Checks if DB is connected
*/
void checkDatabaseConnection();

if (String(env.NODE_ENV) !== 'test') {
/**
* Checks if DB is connected
*/
void checkDatabaseConnection();
}
/**
* Event listener for HTTP server "error" event.
*/
Expand Down
24 changes: 23 additions & 1 deletion services/eventsService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Calendar, Event } from '@prisma/client';
import { eventWithAttendees } from '../@types/apiReponse';
import prisma from '../prisma/prisma';

Expand Down Expand Up @@ -69,4 +70,25 @@ const findEventFromCalendar = async (
}
};

export { findEvent, findEventFromCalendar };
const findCalendarWithId = async (
calendarId: number
): Promise<Calendar | null> => {
const calendarData = await prisma.calendar.findUnique({
where: { id: calendarId },
});
return calendarData;
};

const findEventWithId = async (eventId: number): Promise<Event | null> => {
const eventResponse = await prisma.event.findUnique({
where: { id: +eventId },
});
return eventResponse;
};

export {
findEvent,
findEventFromCalendar,
findCalendarWithId,
findEventWithId,
};
2 changes: 1 addition & 1 deletion utils/prisma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import prisma from '../prisma/prisma';
async function checkDatabaseConnection(): Promise<void> {
try {
await prisma.$connect();
logger.error('Database connected.');
logger.info('Database connected.');
} catch (error) {
logger.error('Database connection failed:', error);
process.exit(1);
Expand Down

0 comments on commit c866309

Please sign in to comment.