diff --git a/index.js b/index.js index b1ed281..b8082bd 100644 --- a/index.js +++ b/index.js @@ -16,6 +16,7 @@ import usersRouter from './routes/users'; import rolesRouter from './routes/roles'; import doctorsRouter from './routes/doctors'; import patientsRouter from './routes/patients'; +import servicesRouter from './routes/services'; import companiesRouter from './routes/companies'; import hospitalsRouter from './routes/hospitals'; @@ -50,6 +51,7 @@ app.use('/api/users', usersRouter); app.use('/api/roles', rolesRouter); app.use('/api/doctors', doctorsRouter); app.use('/api/patients', patientsRouter); +app.use('/api/services', servicesRouter); app.use('/api/companies', companiesRouter); app.use('/api/hospitals', hospitalsRouter); diff --git a/modules/permissionManager.js b/modules/permissionManager.js index 649e4fe..229c779 100644 --- a/modules/permissionManager.js +++ b/modules/permissionManager.js @@ -47,6 +47,7 @@ export async function verifyPermissions(userId, permissionName, permissionType) } export async function checkIfUserEmailIsVerified(userId) { + if(process.env.DISABLE_EMAIL_VERIFICATION) return true; try { const [user] = await pool.execute('SELECT email_verified FROM users WHERE id = ? LIMIT 1', [userId]); if (user.length === 0) return false; diff --git a/routes/doctors.js b/routes/doctors.js index ba26843..8532eee 100644 --- a/routes/doctors.js +++ b/routes/doctors.js @@ -83,10 +83,13 @@ router.post('/:doctorId/validate', verifyToken, checkBanned, checkPermissions('d const { doctor_id } = req.body; if (doctor_id) { try { - const [result] = await pool.execute('UPDATE doctors SET is_verified = 1 WHERE id = ?', [doctor_id]); - if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error validating doctor'); - const [result2] = await pool.execute('INSERT INTO user_roles (user_id, role_id) VALUES (?, (SELECT id FROM roles WHERE name = ? LIMIT 1))', [req.userId, 'Doctor']); - if (result2.affectedRows === 0) return await respondWithStatus(res, 500, 'Error adding role to user'); + const [result] = await pool.execute('SELECT * FROM doctors WHERE id = ?',[doctor_id]); + if(result.length === 0) return await respondWithStatus(res, 404, 'Doctor not found'); + if(result[0].is_verified) return await respondWithStatus(res, 400, 'Doctor already verified'); + const [result2] = await pool.execute('UPDATE doctors SET is_verified = 1 WHERE id = ?', [doctor_id]); + if (result2.affectedRows === 0) return await respondWithStatus(res, 500, 'Error validating doctor'); + const [result3] = await pool.execute('INSERT INTO user_roles (user_id, role_id) VALUES (?, (SELECT id FROM roles WHERE name = ? LIMIT 1))', [result[0].user_id, 'Doctor']); + if (result3.affectedRows === 0) return await respondWithStatus(res, 500, 'Error adding role to user'); return await respondWithStatus(res, 200, 'Doctor validated successfully'); } catch (err) { @@ -436,6 +439,25 @@ router.delete('/:doctorId/services/:serviceId', verifyToken, checkBanned, async } }); +router.get('/:doctorId/hospitals', verifyToken, checkBanned, async (req,res) => { + const doctorId = await getDoctorId(req.userId); + if (req.params.doctorId == '@me') { + if (!doctorId) return await respondWithStatus(res, 404, 'Doctor not found'); + req.params.doctorId = doctorId; + } + if (doctorId != req.params.doctorId && !verifyPermissions(req.userId, 'service', 4)) return await respondWithStatus(res, 403, 'Missing permission'); + try { + //'SELECT s.* FROM services s INNER JOIN service_doctors sd ON s.id = sd.service_id WHERE sd.doctor_id = ?', [req.params.doctorId] + const [rows] = await pool.execute('SELECT h.* FROM hospitals h INNER JOIN hospital_doctors hd ON h.id = hd.hospital_id WHERE hd.doctor_id = ?', [req.params.doctorId]); + if (rows.length === 0) return await respondWithStatus(res, 404, 'Hospitals not found'); + return await respondWithStatusJSON(res, 200, rows); + } + catch (err) { + error(err); + return await respondWithStatus(res, 500, 'An error has occured'); + } +}) + export default router; diff --git a/routes/hospitals.js b/routes/hospitals.js index ed72538..eb65eee 100644 --- a/routes/hospitals.js +++ b/routes/hospitals.js @@ -85,7 +85,7 @@ router.put('/:hospitalId', verifyToken, checkBanned, checkPermissions('hospital' return await respondWithStatus(res, 404, 'Hospital not found'); } const [result] = await pool.execute( - 'UPDATE hospitals SET company_id = ?, name = ?, country = ?, region = ?, city = ?, address = ? WHERE id = ?', + 'UPDATE hospitals SET company_id = ?, name = ?, code = ?, country = ?, region = ?, city = ?, address = ? WHERE id = ?', [company_id, name, code, country, region, city, address, id], ); diff --git a/routes/services.js b/routes/services.js new file mode 100644 index 0000000..690281a --- /dev/null +++ b/routes/services.js @@ -0,0 +1,122 @@ +import express from 'express'; +import { error } from '../modules/logManager'; +import { pool } from '../modules/databaseManager'; +import { verifyToken } from '../modules/tokenManager'; +import { checkPermissions, checkBanned } from '../modules/permissionManager'; +import { respondWithStatus, respondWithStatusJSON } from '../modules/requestHandler'; + +const router = express.Router(); + +router.get('/', verifyToken, checkBanned, checkPermissions('service', 1), async (req, res) => { + try { + const [rows] = await pool.execute('SELECT * FROM services WHERE 1'); + if (rows.length === 0) return await respondWithStatus(res, 404, 'Services not found'); + return await respondWithStatusJSON(res, 200, rows); + } + catch (err) { + error(err); + return await respondWithStatus(res, 500, 'An error has occured'); + } +}); + +router.post('/', verifyToken, checkBanned, checkPermissions('service', 2), async (req, res) => { + const { name, description, price } = req.body; + if ([ name, description, price ].every(Boolean)) { + try { + const [result] = await pool.execute( + 'INSERT INTO services (name, description, price) VALUES (?, ?, ?)', + [ name, description, price ], + ); + if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing service'); + return await respondWithStatus(res, 200, 'Service created successfully'); + } + catch (err) { + error(err); + return await respondWithStatus(res, 500, 'An error has occured'); + } + } + else { + return await respondWithStatus(res, 400, 'Missing fields'); + } +}); + +router.get('/:serviceId', verifyToken, checkBanned, checkPermissions('service', 1), async (req, res) => { + try { + const [rows] = await pool.execute('SELECT * FROM services WHERE id = ? LIMIT 1', [req.params.serviceId]); + if (rows.length === 0) return await respondWithStatus(res, 404, 'Services not found'); + return await respondWithStatusJSON(res, 200, rows[0]); + } + catch (err) { + error(err); + return await respondWithStatus(res, 500, 'An error has occured'); + } +}); + +router.patch('/:serviceId', verifyToken, checkBanned, checkPermissions('service', 2), async (req, res) => { + try { + const { type, value } = req.body; + const [rows] = await pool.execute('SELECT * FROM services WHERE id = ? LIMIT 1', [req.params.serviceId]); + if (rows.length === 0) return await respondWithStatus(res, 404, 'Service not found'); + + const fields = rows.map(row => Object.keys(row)); + if (fields[0].includes(type)) { + const [result] = await pool.execute(`UPDATE services SET ${type} = ? WHERE id = ?`, [value, req.params.serviceId]); + if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error updating service'); + return await respondWithStatus(res, 200, 'Service updated successfully'); + } + else { + return await respondWithStatus(res, 400, 'Invalid type'); + } + } + catch (err) { + error(err); + return await respondWithStatus(res, 500, 'An error has occured'); + } +}); + +router.put('/:serviceId', verifyToken, checkBanned, checkPermissions('service', 2), async (req, res) => { + const id = req.params.serviceId; + const { name, description, price } = req.body; + if ([ name, description, price ].every(Boolean)) { + try { + const [rows] = await pool.execute('SELECT * FROM services WHERE id = ? LIMIT 1', [id]); + + if (rows.length === 0) { + return await respondWithStatus(res, 404, 'Service not found'); + } + const [result] = await pool.execute( + 'UPDATE services SET name = ?, description = ?, price = ? WHERE id = ?', + [name, description, price, id], + ); + + if (result.affectedRows === 0) { + return await respondWithStatus(res, 500, 'Error updating Service'); + } + return await respondWithStatus(res, 200, 'Service updated successfully'); + } + catch (err) { + error(err); + return await respondWithStatus(res, 500, 'An error has occured'); + } + } + else { + return await respondWithStatus(res, 400, 'Missing fields'); + } +}); + +router.delete('/:serviceId', verifyToken, checkBanned, checkPermissions('service', 4), async (req, res) => { + try { + const [rows] = await pool.execute('SELECT * FROM services WHERE id = ? LIMIT 1', [req.params.serviceId]); + if (rows.length === 0) return await respondWithStatus(res, 404, 'service not found'); + + const [result] = await pool.execute('DELETE FROM services WHERE id = ?', [req.params.serviceId]); + if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing Service'); + return await respondWithStatus(res, 200, 'Service deleted successfully'); + } + catch (err) { + error(err); + return await respondWithStatus(res, 500, 'An error has occured'); + } +}); + +export default router; \ No newline at end of file diff --git a/routes/users.js b/routes/users.js index 6e98774..8fe7952 100644 --- a/routes/users.js +++ b/routes/users.js @@ -335,7 +335,7 @@ router.get('/:userId/roles', verifyToken, checkBanned, async (req, res) => { if (req.params.userId != req.userId && !verifyPermissions(req.userId, 'user', 1)) return await respondWithStatus(res, 403, 'Missing permission'); const [rows] = await pool.execute('SELECT r.* FROM users u INNER JOIN user_roles ur ON u.id = ur.user_id INNER JOIN roles r ON ur.role_id = r.id WHERE u.id = ?', [ req.params.userId ]); if (rows.length === 0) return await respondWithStatus(res, 404, 'No roles found'); - return await respondWithStatusJSON(res, rows); + return await respondWithStatusJSON(res, 200, rows); } catch (err) { error(err);