Role update

- Added verify status to user login
- Added option to disable email verification
- Added roles route
- Added role management to users
This commit is contained in:
2024-03-24 11:14:03 +01:00
parent 6452ec2dba
commit 4fbc9819e8
5 changed files with 144 additions and 1 deletions

View File

@@ -7,4 +7,5 @@ DATABASE_PASSWORD=""
JWT_SECRET=""
SMTP=
MAIL=
MAIL_PASS=
MAIL_PASS=
DISABLE_EMAIL_VERIFICATION=true

BIN
bun.lockb

Binary file not shown.

View File

@@ -10,6 +10,7 @@ import { speedLimiter, checkSystemLoad } from './modules/requestHandler';
import testRouter from './routes/test';
import usersRouter from './routes/users';
import rolesRouter from './routes/roles';
import doctorsRouter from './routes/doctors';
import patientsRouter from './routes/patients';
import companiesRouter from './routes/companies';
@@ -37,6 +38,7 @@ app.use(express.static('public'));
// routes
app.use('/api/test', testRouter);
app.use('/api/users', usersRouter);
app.use('/api/roles', rolesRouter);
app.use('/api/doctors', doctorsRouter);
app.use('/api/patients', patientsRouter);
app.use('/api/companies', companiesRouter);

92
routes/roles.js Normal file
View File

@@ -0,0 +1,92 @@
import express from 'express';
import { error } from '../modules/logManager';
import { pool } from '../modules/databaseManager';
import { verifyToken } from '../modules/tokenManager';
import { respondWithStatus, respondWithStatusJSON } from '../modules/requestHandler';
import { checkBanned, checkPermissions } from '../modules/permissionManager';
const router = express.Router();
// GET role list
router.get('/', verifyToken, checkBanned, checkPermissions('role', 1), async (req, res) => {
try {
const rows = await pool.execute('SELECT * FROM roles');
if (rows[0].length === 0) return await respondWithStatus(res, 404, 'No roles found');
return await respondWithStatusJSON(res, rows[0]);
}
catch (err) {
error(err);
return await respondWithStatus(res, 500, 'An error has occured');
}
});
// POST create role
router.post('/', verifyToken, checkBanned, checkPermissions('role', 2), async (req, res) => {
const { name, user_bitfield, role_bitfield, verification_code_bitfield, ban_bitfield, patient_bitfield, doctor_bitfield, service_bitfield, company_bitfield, hospital_bitfield, room_bitfield, appointment_bitfield } = req.body;
if ([ name, user_bitfield, role_bitfield, verification_code_bitfield, ban_bitfield, patient_bitfield, doctor_bitfield, service_bitfield, company_bitfield, hospital_bitfield, room_bitfield, appointment_bitfield ].every(Boolean)) {
try {
await pool.execute(
'INSERT INTO users (name, user_bitfield, role_bitfield, verification_code_bitfield, ban_bitfield, patient_bitfield, doctor_bitfield, service_bitfield, company_bitfield, hospital_bitfield, room_bitfield, appointment_bitfield) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
[ name, user_bitfield, role_bitfield, verification_code_bitfield, ban_bitfield, patient_bitfield, doctor_bitfield, service_bitfield, company_bitfield, hospital_bitfield, room_bitfield, appointment_bitfield ],
);
return await respondWithStatus(res, 200, 'Role created successfully');
}
catch (err) {
error(err);
return await respondWithStatus(res, 500, 'An error has occured');
}
}
else {
return await respondWithStatus(res, 400, 'Missing fields');
}
});
// GET role
router.get('/:id', verifyToken, checkBanned, checkPermissions('role', 1), async (req, res) => {
try {
const [rows] = await pool.execute('SELECT * FROM roles WHERE id = ? LIMIT 1', [ req.params.id ]);
if (rows.length === 0) return await respondWithStatus(res, 404, 'Role not found');
return await respondWithStatusJSON(res, rows[0]);
}
catch (err) {
error(err);
return await respondWithStatus(res, 500, 'An error has occured');
}
});
// PUT update role
router.put('/:id', verifyToken, checkBanned, checkPermissions('role', 2), async (req, res) => {
const { name, user_bitfield, role_bitfield, verification_code_bitfield, ban_bitfield, patient_bitfield, doctor_bitfield, service_bitfield, company_bitfield, hospital_bitfield, room_bitfield, appointment_bitfield } = req.body;
if ([ name, user_bitfield, role_bitfield, verification_code_bitfield, ban_bitfield, patient_bitfield, doctor_bitfield, service_bitfield, company_bitfield, hospital_bitfield, room_bitfield, appointment_bitfield ].every(Boolean)) {
try {
await pool.execute(
'UPDATE roles SET name = ?, user_bitfield = ?, role_bitfield = ?, verification_code_bitfield = ?, ban_bitfield = ?, patient_bitfield = ?, doctor_bitfield = ?, service_bitfield = ?, company_bitfield = ?, hospital_bitfield = ?, room_bitfield = ?, appointment_bitfield = ? WHERE id = ?',
[ name, user_bitfield, role_bitfield, verification_code_bitfield, ban_bitfield, patient_bitfield, doctor_bitfield, service_bitfield, company_bitfield, hospital_bitfield, room_bitfield, appointment_bitfield, req.params.id ],
);
return await respondWithStatus(res, 200, 'Role updated successfully');
}
catch (err) {
error(err);
return await respondWithStatus(res, 500, 'An error has occured');
}
}
else {
return await respondWithStatus(res, 400, 'Missing fields');
}
});
// DELETE role
router.delete('/:id', verifyToken, checkBanned, checkPermissions('role', 4), async (req, res) => {
try {
await pool.execute('DELETE FROM roles WHERE id = ?', [ req.params.id ]);
return await respondWithStatus(res, 200, 'Role deleted successfully');
}
catch (err) {
error(err);
return await respondWithStatus(res, 500, 'An error has occured');
}
});
export default router;

View File

@@ -30,6 +30,8 @@ router.post('/register', requestLimiter, async (req, res) => {
);
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error storing user');
if (process.env.DISABLE_EMAIL_VERIFICATION) return await respondWithStatus(res, 200, 'Successfully registered');
const [rows] = await pool.execute('SELECT id FROM users WHERE email = ? LIMIT 1', [email]);
const code = sendVerification(email, rows[0].id, 'email');
pool.execute('INSERT INTO verification_codes (user_id, verification_code, type) VALUES (?, ?, ?)', [ rows[0].id, code, 'email' ]);
@@ -74,6 +76,7 @@ router.post('/login', requestLimiter, async (req, res) => {
email: user.email,
first_name: user.first_name,
last_name: user.last_name,
verified_status: process.env.DISABLE_EMAIL_VERIFICATION ? true : user.email_verified,
},
});
}
@@ -322,4 +325,49 @@ router.delete('/:userId', verifyToken, checkBanned, async (req, res) => {
}
});
router.get('/:userId/roles', verifyToken, checkBanned, async (req, res) => {
try {
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);
}
catch (err) {
error(err);
return await respondWithStatus(res, 500, 'An error has occured');
}
});
router.post('/:userId/roles', verifyToken, checkBanned, checkPermissions('user', 2), async (req, res) => {
const { roleId } = req.body;
if (roleId) {
try {
const [rows] = await pool.execute('SELECT * FROM roles WHERE id = ? LIMIT 1', [ roleId ]);
if (rows.length === 0) return await respondWithStatus(res, 404, 'Role not found');
const [result] = await pool.execute('INSERT INTO user_roles (user_id, role_id) VALUES (?, ?)', [ req.params.userId, roleId ]);
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error assigning role');
return await respondWithStatus(res, 200, 'Role assigned successfully');
}
catch (err) {
error(err);
return await respondWithStatus(res, 500, 'An error has occured');
}
}
else {
return await respondWithStatus(res, 400, 'Missing fields');
}
});
router.delete('/:userId/roles/:roleId', verifyToken, checkBanned, checkPermissions('user', 4), async (req, res) => {
try {
const [result] = await pool.execute('DELETE FROM user_roles WHERE user_id = ? AND role_id = ?', [ req.params.userId, req.params.roleId ]);
if (result.affectedRows === 0) return await respondWithStatus(res, 500, 'Error removing role');
return await respondWithStatus(res, 200, 'Role removed successfully');
}
catch (err) {
error(err);
return await respondWithStatus(res, 500, 'An error has occured');
}
});
export default router;