Refactor user route
							parent
							
								
									f43005de8b
								
							
						
					
					
						commit
						1deb54d525
					
				
							
								
								
									
										337
									
								
								routes/user.js
								
								
								
								
							
							
						
						
									
										337
									
								
								routes/user.js
								
								
								
								
							|  | @ -5,61 +5,69 @@ const colors = require('colors'); | |||
| const bcrypt = require('bcryptjs'); | ||||
| const router = express.Router(); | ||||
| 
 | ||||
| router.get('/admin/users', restrict, (req, res) => { | ||||
| router.get('/admin/users', restrict, async (req, res) => { | ||||
|     const db = req.app.db; | ||||
|     db.users.find({}).toArray((err, users) => { | ||||
|         if(err){ | ||||
|             console.info(err.stack); | ||||
|         } | ||||
|         res.render('users', { | ||||
|             title: 'Users', | ||||
|             users: users, | ||||
|             admin: true, | ||||
|             config: req.app.config, | ||||
|             isAdmin: req.session.isAdmin, | ||||
|             helpers: req.handlebars.helpers, | ||||
|             session: req.session, | ||||
|             message: common.clearSessionValue(req.session, 'message'), | ||||
|             messageType: common.clearSessionValue(req.session, 'messageType') | ||||
|         }); | ||||
|     const users = await db.users.find({}, { projection: { userPassword: 0 } }).toArray(); | ||||
| 
 | ||||
|     if(req.apiAuthenticated){ | ||||
|         res.status(200).json(users); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     res.render('users', { | ||||
|         title: 'Users', | ||||
|         users: users, | ||||
|         admin: true, | ||||
|         config: req.app.config, | ||||
|         isAdmin: req.session.isAdmin, | ||||
|         helpers: req.handlebars.helpers, | ||||
|         session: req.session, | ||||
|         message: common.clearSessionValue(req.session, 'message'), | ||||
|         messageType: common.clearSessionValue(req.session, 'messageType') | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
| // edit user
 | ||||
| router.get('/admin/user/edit/:id', restrict, (req, res) => { | ||||
| router.get('/admin/user/edit/:id', restrict, async (req, res) => { | ||||
|     const db = req.app.db; | ||||
|     db.users.findOne({ _id: common.getId(req.params.id) }, (err, user) => { | ||||
|         if(err){ | ||||
|             console.info(err.stack); | ||||
|         } | ||||
|     const user = await db.users.findOne({ _id: common.getId(req.params.id) }); | ||||
| 
 | ||||
|         // Check user is found
 | ||||
|         if(!user){ | ||||
|             req.session.message = 'User not found'; | ||||
|             req.session.messageType = 'danger'; | ||||
|             res.redirect('/admin/users'); | ||||
|     // Check user is found
 | ||||
|     if(!user){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'User not found' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // if the user we want to edit is not the current logged in user and the current user is not
 | ||||
|         // an admin we render an access denied message
 | ||||
|         if(user.userEmail !== req.session.user && req.session.isAdmin === false){ | ||||
|             req.session.message = 'Access denied'; | ||||
|             req.session.messageType = 'danger'; | ||||
|             res.redirect('/admin/users'); | ||||
|         req.session.message = 'User not found'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // if the user we want to edit is not the current logged in user and the current user is not
 | ||||
|     // an admin we render an access denied message
 | ||||
|     if(user.userEmail !== req.session.user && req.session.isAdmin === false){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'Access denied' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         res.render('user_edit', { | ||||
|             title: 'User edit', | ||||
|             user: user, | ||||
|             admin: true, | ||||
|             session: req.session, | ||||
|             message: common.clearSessionValue(req.session, 'message'), | ||||
|             messageType: common.clearSessionValue(req.session, 'messageType'), | ||||
|             helpers: req.handlebars.helpers, | ||||
|             config: req.app.config | ||||
|         }); | ||||
|         req.session.message = 'Access denied'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     res.render('user_edit', { | ||||
|         title: 'User edit', | ||||
|         user: user, | ||||
|         admin: true, | ||||
|         session: req.session, | ||||
|         message: common.clearSessionValue(req.session, 'message'), | ||||
|         messageType: common.clearSessionValue(req.session, 'messageType'), | ||||
|         helpers: req.handlebars.helpers, | ||||
|         config: req.app.config | ||||
|     }); | ||||
| }); | ||||
| 
 | ||||
|  | @ -82,6 +90,11 @@ router.get('/admin/user/delete/:id', restrict, async (req, res) => { | |||
| 
 | ||||
|     // userId
 | ||||
|     if(req.session.isAdmin !== true){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'Access denied' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         req.session.message = 'Access denied.'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|  | @ -90,6 +103,11 @@ router.get('/admin/user/delete/:id', restrict, async (req, res) => { | |||
| 
 | ||||
|     // Cannot delete your own account
 | ||||
|     if(req.session.userId === req.params.id){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'Unable to delete own user account' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         req.session.message = 'Unable to delete own user account.'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|  | @ -100,6 +118,11 @@ router.get('/admin/user/delete/:id', restrict, async (req, res) => { | |||
| 
 | ||||
|     // If user is not found
 | ||||
|     if(!user){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'User not found.' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         req.session.message = 'User not found.'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|  | @ -108,139 +131,179 @@ router.get('/admin/user/delete/:id', restrict, async (req, res) => { | |||
| 
 | ||||
|     // Cannot delete the original user/owner
 | ||||
|     if(user.isOwner){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'Access denied.' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         req.session.message = 'Access denied.'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     db.users.deleteOne({ _id: common.getId(req.params.id) }, {}, (err, numRemoved) => { | ||||
|         if(err){ | ||||
|             console.info(err.stack); | ||||
|     try{ | ||||
|         await db.users.deleteOne({ _id: common.getId(req.params.id) }, {}); | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(200).json({ message: 'User deleted.' }); | ||||
|             return; | ||||
|         } | ||||
|         req.session.message = 'User deleted.'; | ||||
|         req.session.messageType = 'success'; | ||||
|         res.redirect('/admin/users'); | ||||
|     }); | ||||
|     }catch(ex){ | ||||
|         console.log('Failed to delete user', ex); | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(200).json({ message: 'Cannot delete user' }); | ||||
|             return; | ||||
|         } | ||||
|         req.session.message = 'Cannot delete user'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|     }; | ||||
| }); | ||||
| 
 | ||||
| // update a user
 | ||||
| router.post('/admin/user/update', restrict, (req, res) => { | ||||
| router.post('/admin/user/update', restrict, async (req, res) => { | ||||
|     const db = req.app.db; | ||||
| 
 | ||||
|     let isAdmin = req.body.user_admin === 'on'; | ||||
| 
 | ||||
|     // get the user we want to update
 | ||||
|     db.users.findOne({ _id: common.getId(req.body.userId) }, (err, user) => { | ||||
|         if(err){ | ||||
|             console.info(err.stack); | ||||
|         } | ||||
|     const user = await db.users.findOne({ _id: common.getId(req.body.userId) }); | ||||
| 
 | ||||
|         // If the current user changing own account ensure isAdmin retains existing
 | ||||
|         if(user.userEmail === req.session.user){ | ||||
|             isAdmin = user.isAdmin; | ||||
|         } | ||||
| 
 | ||||
|         // if the user we want to edit is not the current logged in user and the current user is not
 | ||||
|         // an admin we render an access denied message
 | ||||
|         if(user.userEmail !== req.session.user && req.session.isAdmin === false){ | ||||
|             req.session.message = 'Access denied'; | ||||
|             req.session.messageType = 'danger'; | ||||
|             res.redirect('/admin/users'); | ||||
|     // If user not found
 | ||||
|     if(!user){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'User not found' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // create the update doc
 | ||||
|         const updateDoc = {}; | ||||
|         updateDoc.isAdmin = isAdmin; | ||||
|         updateDoc.usersName = req.body.usersName; | ||||
|         if(req.body.userPassword){ | ||||
|             updateDoc.userPassword = bcrypt.hashSync(req.body.userPassword); | ||||
|         req.session.message = 'User not found'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // If the current user changing own account ensure isAdmin retains existing
 | ||||
|     if(user.userEmail === req.session.user){ | ||||
|         isAdmin = user.isAdmin; | ||||
|     } | ||||
| 
 | ||||
|     // if the user we want to edit is not the current logged in user and the current user is not
 | ||||
|     // an admin we render an access denied message
 | ||||
|     if(user.userEmail !== req.session.user && req.session.isAdmin === false){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'Access denied' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         db.users.updateOne({ _id: common.getId(req.body.userId) }, | ||||
|         req.session.message = 'Access denied'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/users'); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     // create the update doc
 | ||||
|     const updateDoc = {}; | ||||
|     updateDoc.isAdmin = isAdmin; | ||||
|     updateDoc.usersName = req.body.usersName; | ||||
|     if(req.body.userPassword){ | ||||
|         updateDoc.userPassword = bcrypt.hashSync(req.body.userPassword); | ||||
|     } | ||||
| 
 | ||||
|     try{ | ||||
|         await db.users.updateOne( | ||||
|             { _id: common.getId(req.body.userId) }, | ||||
|             { | ||||
|                 $set: updateDoc | ||||
|             }, { multi: false }, (err, numReplaced) => { | ||||
|                 if(err){ | ||||
|                     console.error(colors.red('Failed updating user: ' + err)); | ||||
|                     req.session.message = 'Failed to update user'; | ||||
|                     req.session.messageType = 'danger'; | ||||
|                     res.redirect('/admin/user/edit/' + req.body.userId); | ||||
|                 }else{ | ||||
|                     // show the view
 | ||||
|                     req.session.message = 'User account updated.'; | ||||
|                     req.session.messageType = 'success'; | ||||
|                     res.redirect('/admin/user/edit/' + req.body.userId); | ||||
|                 } | ||||
|             }); | ||||
|     }); | ||||
|             }, { multi: false } | ||||
|         ); | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(200).json({ message: 'User account updated.' }); | ||||
|             return; | ||||
|         } | ||||
|         // show the view
 | ||||
|         req.session.message = 'User account updated.'; | ||||
|         req.session.messageType = 'success'; | ||||
|         res.redirect('/admin/user/edit/' + req.body.userId); | ||||
|     }catch(ex){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'Failed to update user' }); | ||||
|             return; | ||||
|         } | ||||
|         console.error(colors.red('Failed updating user: ' + ex)); | ||||
|         req.session.message = 'Failed to update user'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/user/edit/' + req.body.userId); | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| // insert a user
 | ||||
| router.post('/admin/user/insert', restrict, (req, res) => { | ||||
| router.post('/admin/user/insert', restrict, async (req, res) => { | ||||
|     const db = req.app.db; | ||||
| 
 | ||||
|     // set the account to admin if using the setup form. Eg: First user account
 | ||||
|     const urlParts = new URL(req.header('Referer')); | ||||
| 
 | ||||
|     // Check number of users
 | ||||
|     db.users.countDocuments({}, (err, userCount) => { | ||||
|         let isAdmin = false; | ||||
|     const userCount = await db.users.countDocuments({}); | ||||
|     let isAdmin = false; | ||||
| 
 | ||||
|         // if no users, setup user as admin
 | ||||
|         if(userCount === 0){ | ||||
|             isAdmin = true; | ||||
|     // if no users, setup user as admin
 | ||||
|     if(userCount === 0){ | ||||
|         isAdmin = true; | ||||
|     } | ||||
| 
 | ||||
|     const doc = { | ||||
|         usersName: req.body.usersName, | ||||
|         userEmail: req.body.userEmail, | ||||
|         userPassword: bcrypt.hashSync(req.body.userPassword, 10), | ||||
|         isAdmin: isAdmin | ||||
|     }; | ||||
| 
 | ||||
|     // check for existing user
 | ||||
|     const user = await db.users.findOne({ userEmail: req.body.userEmail }); | ||||
|     if(user){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'A user with that email address already exists' }); | ||||
|             return; | ||||
|         } | ||||
|         // user already exists with that email address
 | ||||
|         console.error(colors.red('Failed to insert user, possibly already exists: ' + err)); | ||||
|         req.session.message = 'A user with that email address already exists'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/user/new'); | ||||
|         return; | ||||
|     } | ||||
|     // email is ok to be used.
 | ||||
|     try{ | ||||
|         await db.users.insertOne(doc); | ||||
|         // if from setup we add user to session and redirect to login.
 | ||||
|         // Otherwise we show users screen
 | ||||
|         if(urlParts.path === '/admin/setup'){ | ||||
|             req.session.user = req.body.userEmail; | ||||
|             res.redirect('/admin/login'); | ||||
|             return; | ||||
|         } | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(200).json({ message: 'User account inserted' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const doc = { | ||||
|             usersName: req.body.usersName, | ||||
|             userEmail: req.body.userEmail, | ||||
|             userPassword: bcrypt.hashSync(req.body.userPassword, 10), | ||||
|             isAdmin: isAdmin | ||||
|         }; | ||||
| 
 | ||||
|         // check for existing user
 | ||||
|         db.users.findOne({ userEmail: req.body.userEmail }, (err, user) => { | ||||
|             if(user){ | ||||
|                 // user already exists with that email address
 | ||||
|                 console.error(colors.red('Failed to insert user, possibly already exists: ' + err)); | ||||
|                 req.session.message = 'A user with that email address already exists'; | ||||
|                 req.session.messageType = 'danger'; | ||||
|                 res.redirect('/admin/user/new'); | ||||
|                 return; | ||||
|             } | ||||
|             // email is ok to be used.
 | ||||
|             db.users.insertOne(doc, (err, doc) => { | ||||
|                 // show the view
 | ||||
|                 if(err){ | ||||
|                     if(doc){ | ||||
|                         console.error(colors.red('Failed to insert user: ' + err)); | ||||
|                         req.session.message = 'User exists'; | ||||
|                         req.session.messageType = 'danger'; | ||||
|                         res.redirect('/admin/user/edit/' + doc._id); | ||||
|                         return; | ||||
|                     } | ||||
|                     console.error(colors.red('Failed to insert user: ' + err)); | ||||
|                     req.session.message = 'New user creation failed'; | ||||
|                     req.session.messageType = 'danger'; | ||||
|                     res.redirect('/admin/user/new'); | ||||
|                     return; | ||||
|                 } | ||||
|                 req.session.message = 'User account inserted'; | ||||
|                 req.session.messageType = 'success'; | ||||
| 
 | ||||
|                 // if from setup we add user to session and redirect to login.
 | ||||
|                 // Otherwise we show users screen
 | ||||
|                 if(urlParts.path === '/admin/setup'){ | ||||
|                     req.session.user = req.body.userEmail; | ||||
|                     res.redirect('/admin/login'); | ||||
|                     return; | ||||
|                 } | ||||
|                 res.redirect('/admin/users'); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
|         req.session.message = 'User account inserted'; | ||||
|         req.session.messageType = 'success'; | ||||
|         res.redirect('/admin/users'); | ||||
|     }catch(ex){ | ||||
|         if(req.apiAuthenticated){ | ||||
|             res.status(400).json({ message: 'New user creation failed' }); | ||||
|             return; | ||||
|         } | ||||
|         console.error(colors.red('Failed to insert user: ' + ex)); | ||||
|         req.session.message = 'New user creation failed'; | ||||
|         req.session.messageType = 'danger'; | ||||
|         res.redirect('/admin/user/new'); | ||||
|     } | ||||
| }); | ||||
| 
 | ||||
| module.exports = router; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue