diff --git a/.env b/.env deleted file mode 100644 index b3515763cb46d9a84b2aacfaef651258d7bda6b6..0000000000000000000000000000000000000000 --- a/.env +++ /dev/null @@ -1,7 +0,0 @@ -PORT=7999 -INSTANCE=TEST -HOST=localhost -USER=root -PASSWORD=password -DB=parameter_database -AUTH_BASE_URL=http://localhost:4000/users \ No newline at end of file diff --git a/.gitignore b/.gitignore index c6bdbb76309d8f805e24c9ab3df8f1ffde34d075..44de9c142df1ec9f16877686c392a9108536d639 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ build npm-debug.log .DS_Store logs/ + +.env \ No newline at end of file diff --git a/src/Controllers/FAQController.ts b/src/Controllers/FAQController.ts index 4ed26253f4da0d96a5a3029b34e78d272a6d9d19..642a82d3e6e3789ecfa19b294eda57b3103b8a1b 100644 --- a/src/Controllers/FAQController.ts +++ b/src/Controllers/FAQController.ts @@ -2,6 +2,7 @@ import { Request, Response, Router } from 'express'; import FAQ from '../Models/FAQ'; import FAQService from '../Services/FAQService'; import { FAQDTO } from '../DTOs/FAQDTO'; +import AuthMiddleware from '../Middlewares/authChecker'; const router = Router(); @@ -18,8 +19,11 @@ const list = async (req: Request, res: Response): Promise<Response> => { const create = async (req: Request, res: Response): Promise<Response> => { try { const dto: FAQDTO = req.body; - const newFAQ: FAQ = await FAQService.create(dto); - return res.status(200).send(newFAQ); + const newFAQ: FAQ | null = await FAQService.create(dto); + if (newFAQ) { + return res.status(200).send(newFAQ); + } + return res.status(400).send('create error'); } catch (error) { console.log(error); return res.status(400).send('create error'); @@ -34,7 +38,7 @@ const update = async (req: Request, res: Response): Promise<Response> => { if (updatedFAQ) { return res.status(200).send(updatedFAQ); } - return res.status(400).send('id error'); + return res.status(400).send('update error'); } catch (error) { console.log(error); return res.status(400).send('update error'); @@ -55,7 +59,11 @@ const deleteFAQ = async (req: Request, res: Response): Promise<Response> => { }; router - .get('/', list) + .get('/', list); + +router.use(AuthMiddleware.adminChecker); + +router .post('/', create); router diff --git a/src/Controllers/UserController.ts b/src/Controllers/UserController.ts index 085fd95b7b5f0ba88e73da922673b3e25bf858b1..4ce2ff43ac46504c6c9244b6f97e5bccb9a12d0b 100644 --- a/src/Controllers/UserController.ts +++ b/src/Controllers/UserController.ts @@ -4,7 +4,7 @@ import { Handler, Request, Response, Router, } from 'express'; -import UserAPI from '../Services/UserAPI'; +import UserAPI, { checkUser as checkUserFromAPI } from '../Services/UserAPI'; const router = Router(); @@ -109,7 +109,7 @@ const removeAdminPermission: Handler = async (req: Request, res: Response) => { const checkUser: Handler = async (req: Request, res: Response) => { try { const token: any = req.headers.authorization; - const user: any = await UserAPI.checkUser(token); + const user: any = await checkUserFromAPI(token); return res.status(200).send(user); } catch (error) { const e = error as Error; diff --git a/src/Enum/UserTypes.ts b/src/Enum/UserTypes.ts new file mode 100644 index 0000000000000000000000000000000000000000..a8f4ae3fd8c2337b580a08ea05b870e117c0b0cc --- /dev/null +++ b/src/Enum/UserTypes.ts @@ -0,0 +1,5 @@ +export enum UserTypes { + unassigned = 0, + administrator = 1, + client = 2 +} diff --git a/src/Middlewares/authChecker.ts b/src/Middlewares/authChecker.ts index 21c7f1ae761a5784afc336abb5cbd228fca41e7e..984d8bd8ff2599fecd58594ecec8741b8b14b63a 100644 --- a/src/Middlewares/authChecker.ts +++ b/src/Middlewares/authChecker.ts @@ -1,5 +1,6 @@ import { Response, NextFunction } from 'express'; -import { validate } from '../Services/UserAPI'; +import { validate, checkUser } from '../Services/UserAPI'; +import { UserTypes } from '../Enum/UserTypes'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const authChecker = async (req: any, res: Response, next: NextFunction) => { @@ -13,4 +14,25 @@ const authChecker = async (req: any, res: Response, next: NextFunction) => { } }; -export default authChecker; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const adminChecker = async (req: any, res: Response, next: NextFunction) => { + try { + const token = req.headers.authorization; + const { userId, userType } = await checkUser(token) as { + userId: number; + userType: number; + }; + if (userId && userType && userType === UserTypes.administrator) { + next(); + } else { + res.status(401).send({ message: 'auth failed' }); + } + } catch (error) { + res.status(401).send({ message: 'auth failed' }); + } +}; + +export default { + authChecker, + adminChecker, +}; diff --git a/src/Services/FAQService.ts b/src/Services/FAQService.ts index 6b56f396b10426e85af474f801a152b512f9f762..b667113fe0f72ec8b46057ab54a3bafd99522324 100644 --- a/src/Services/FAQService.ts +++ b/src/Services/FAQService.ts @@ -25,7 +25,13 @@ const correctFAQs = async (faqs: FAQ[]): Promise<void> => new Promise((resolve, .catch(() => reject()); }); -const create = async (createDto: FAQDTO): Promise<FAQ> => { +const checkFAQFormat = (dto: FAQDTO): boolean => !!dto.answer + && !!dto.question && (dto.position) >= 1; + +const create = async (createDto: FAQDTO): Promise<FAQ | null> => { + if (!checkFAQFormat(createDto)) { + return null; + } const faqs: FAQ[] = await FAQ.findAll({ where: { deletedAt: null, @@ -46,6 +52,9 @@ const create = async (createDto: FAQDTO): Promise<FAQ> => { }; const update = async (id: number, createDto: FAQDTO): Promise<FAQ | null> => { + if (!checkFAQFormat(createDto)) { + return null; + } const toUpdate: FAQ | null = await FAQ.findOne({ where: { id, diff --git a/src/Services/UserAPI.ts b/src/Services/UserAPI.ts index 0ae586294914ccfacd1a48d79bca2c169c9fc16b..1c969c91605bb47480d7d41f1b91b6d41fa053cc 100644 --- a/src/Services/UserAPI.ts +++ b/src/Services/UserAPI.ts @@ -82,7 +82,7 @@ const listUsersById = async (userIds: any, token: any) => { return res.data; }; -const checkUser = async (token: string) => { +export const checkUser = async (token: string) => { const url = '/check-user'; const res = await instance.post(url, {}, { headers: { authorization: token } }); return res.data; @@ -105,6 +105,5 @@ export default { giveAdminPermission, removeAdminPermission, listUsersById, - checkUser, getUser, }; diff --git a/src/routes.ts b/src/routes.ts index 1fc5126b113c12cd02e47ace66a7b28c7bc83013..9334fb3375b18db70c4a7216dc7333281b72645d 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -5,7 +5,7 @@ import ParameterController from './Controllers/ParameterController'; import FAQController from './Controllers/FAQController'; import UserController from './Controllers/UserController'; import AuditorController from './Controllers/AuditorController'; -import authChecker from './Middlewares/authChecker'; +import AuthMiddleware from './Middlewares/authChecker'; const router = Router(); @@ -14,8 +14,12 @@ router.get('/', (req: Request, res: Response): void => { }); router.use('/users', UserController); + +// FAQs have authentication on some endpoints +router.use('/faqs', FAQController); // From this line on a auth verification will be taken -router.use(authChecker); + +router.use(AuthMiddleware.authChecker); router.use('/sheetParser', SheetController); @@ -23,8 +27,6 @@ router.use('/repCalculator', CalculatorController); router.use('/parameters', ParameterController); -router.use('/faqs', FAQController); - router.use('/auditory', AuditorController); export default router;