summaryrefslogtreecommitdiffstats
path: root/server/api/users.js
diff options
context:
space:
mode:
Diffstat (limited to 'server/api/users.js')
-rw-r--r--server/api/users.js251
1 files changed, 233 insertions, 18 deletions
diff --git a/server/api/users.js b/server/api/users.js
index 33ad3d3..d69c776 100644
--- a/server/api/users.js
+++ b/server/api/users.js
@@ -5,6 +5,7 @@ var express = require('express')
const { decorateApp } = require('@awaitjs/express')
var router = decorateApp(express.Router())
var authentication = require(path.join(__appdir, 'lib', 'authentication'))
+const log = require(path.join(__appdir, 'lib', 'log'))
// ############################################################################
// ########################### GET requests #################################
@@ -39,12 +40,44 @@ router.postAsync('/roles', async (req, res) => {
const userIds = req.body.users
const roleIds = req.body.roles
- const users = await db.user.findAll({ where: { id: userIds } })
+ const users = await db.user.findAll({ where: { id: userIds }, include: ['roles'] })
+ const userDb = await db.user.findOne({ where: { id: req.user.id } })
if (users) {
if (req.query.delete !== undefined && req.query.delete !== 'false') {
- users.forEach(user => { user.removeRoles(roleIds) })
+ for (let index in users) {
+ const user = users[index]
+ const roles = user.roles
+ const count = await user.removeRoles(roleIds)
+ let roleString = 'role'
+ if (count > 1) roleString += 's'
+ log({
+ category: 'USER_REVOKE_ROLE',
+ description: '[' + user.id + '] ' + user.name + ': Successfully removed ' + count + ' ' + roleString + '.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'Removed Roles: ' + roleIds.filter(y => { return roles.map(x => x.id).includes(y) }),
+ userDb,
+ userId: req.user.id
+ })
+ }
} else {
- users.forEach(user => { user.addRoles(roleIds) })
+ for (let index in users) {
+ const user = users[index]
+ const count = await user.addRoles(roleIds)
+ if (count.length > 0) {
+ let roleString = 'role'
+ if (count[0].length > 1) roleString += 's'
+ log({
+ category: 'USER_GRANT_ROLE',
+ description: '[' + user.id + '] ' + user.name + ': Successfully added ' + count[0].length + ' ' + roleString + '.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'Added Roles: ' + count[0].map(x => x.roleId),
+ userDb,
+ userId: req.user.id
+ })
+ }
+ }
}
res.status(200).end()
} else {
@@ -59,24 +92,116 @@ router.postAsync(['/', '/:id'], async (req, res) => {
// TODO: Check for permission to delete / create / update user
}
+ // Delete request
if (req.query.delete !== undefined && req.query.delete !== 'false') {
- const count = await db.user.destroy({ where: { id: body.ids } })
- return res.send({ count })
+ const user = await db.user.findOne({ where: { id: req.user.id } })
+
+ // Only need to log batch request if there is more than one user to delete.
+ if (req.body.ids.length > 1) {
+ await log({
+ category: 'USER_BATCH_DELETE',
+ description: 'User batch deletion of ' + req.body.ids.length + ' users initiated by user.',
+ user,
+ userId: req.user.id
+ })
+ }
+
+ let deletionCounter = 0
+ let selfdeletion = false
+
+ // Delete every user on its own, to get a better log
+ for (let index in req.body.ids) {
+ // We can't set the userId in the log if we delete ourselfs.
+ if (req.body.ids[index] === req.user.id) selfdeletion = true
+ const userDb = await db.user.findOne({ where: { id: req.body.ids[index] } })
+ const count = await db.user.destroy({ where: { id: req.body.ids[index] } })
+ if (count !== 1) {
+ await log({
+ category: 'ERROR_USER_DELETE',
+ description: '[' + userDb.id + '] ' + userDb.username + ': User could not be deleted.\n' +
+ 'ID: ' + userDb.id + '\n' +
+ 'Username: ' + userDb.username + '\n' +
+ 'Name: ' + userDb.name + '\n' +
+ 'E-Mail: ' + userDb.email + '\n',
+ user,
+ userId: selfdeletion ? undefined : req.user.id
+ })
+ } else {
+ await log({
+ category: 'USER_DELETE',
+ description: '[' + userDb.id + '] ' + userDb.username + ': User successfully deleted.\n' +
+ 'ID: ' + userDb.id + '\n' +
+ 'Username: ' + userDb.username + '\n' +
+ 'Name: ' + userDb.name + '\n' +
+ 'E-Mail: ' + userDb.email + '\n',
+ user,
+ userId: selfdeletion ? undefined : req.user.id
+ })
+ deletionCounter++
+ }
+ }
+ if (req.body.ids.length > 1) {
+ log({
+ category: 'USER_BATCH_DELETE',
+ description: deletionCounter + '/' + req.body.ids.length + ' users successfully deleted.',
+ user,
+ userId: selfdeletion ? undefined : req.user.id
+ })
+ }
+
+ return res.send({ deletionCounter })
}
if (req.params.id === undefined) {
const result = await authentication.signup(body)
const code = result.code
+ const user = await db.user.findOne({ where: { id: result.id } })
+
+ // Create a log entry for the user creation
+ if (code === 200) {
+ log({
+ category: 'USER_CREATE',
+ description: '[' + user.id + '] ' + user.username + ': User successfully created.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ userId: req.user.id
+ })
+ } else {
+ log({
+ category: 'ERROR_USER_CREATE',
+ description: '[' + code + '][' + result.error + '] ' + result.message + '\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ userId: req.user.id
+ })
+ }
+
delete result.code
return res.status(code).send(result)
} else {
const id = req.params.id === 'current' ? req.user.id : req.params.id
+ let user = await db.user.findOne({ where: { id: id } })
let email = req.body.email
- if (!authentication.validateEmail(req.body.email)) return res.status(500).send({ error: 'EMAIL_INVALID', message: 'The provided email is invalid.' })
-
- let user
- user = await db.user.findOne({ where: { id: id } })
+ if (!authentication.validateEmail(req.body.email)) {
+ log({
+ category: 'ERROR_USER_EDIT',
+ description: '[' + user.id + '] ' + user.username + ': User could not be updated. The E-Mail is invalid.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ userId: req.user.id
+ })
+ return res.status(500).send({
+ error: 'EMAIL_INVALID',
+ message: 'The provided email is invalid.'
+ })
+ }
if (user) {
let userinfo = {
@@ -87,20 +212,74 @@ router.postAsync(['/', '/:id'], async (req, res) => {
// Check if the username is set and if it's valid.
let username = body.username
if (username && req.params.id !== 'current') {
- if (!authentication.validateUsername(username)) return res.status(400).send({ error: 'INVALID_USERNAME', message: 'Username does not fullfill the requirements. (No whitespaces)' })
+ if (!authentication.validateUsername(username)) {
+ log({
+ category: 'ERROR_USER_EDIT',
+ description: '[' + user.id + '] ' + user.username + ': User could not be updated. The username does not fullfull the requirements. (No whitespaces)\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ userId: req.user.id
+ })
+ return res.status(400).send({ error: 'INVALID_USERNAME', message: 'Username does not fullfill the requirements. (No whitespaces)' })
+ }
// Check if the username already exists.
let userDb = await db.user.findOne({ where: { username: username, id: { [db.Op.not]: id } } })
- if (userDb) return res.status(400).send({ error: 'USER_ALREADY_EXISTS', message: 'The provided username already exists.' })
+ if (userDb) {
+ log({
+ category: 'ERROR_USER_EDIT',
+ description: '[' + user.id + '] ' + user.username + ': User could not be updated. The username already exists.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ userId: req.user.id
+ })
+ return res.status(400).send({ error: 'USER_ALREADY_EXISTS', message: 'The provided username already exists.' })
+ }
userinfo.username = username
}
// Update the user.
await user.update(userinfo)
+ log({
+ category: 'USER_EDIT',
+ description: '[' + user.id + '] ' + user.username + ': User successfully updated.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ userId: req.user.id
+ })
if (body.password) {
const result = await authentication.changePassword(id, body.password, body.passwordCurrent)
const code = result.code
delete result.code
+
+ if (code === 200) {
+ log({
+ category: 'USER_EDIT_PASSWORD',
+ description: '[' + user.id + '] ' + user.username + ': Password successfully updated.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ userId: req.user.id
+ })
+ } else {
+ log({
+ category: 'ERROR_USER_EDIT_PASSWORD',
+ description: '[' + user.id + '] ' + user.username + ': Password could not be updated. Code ' + code + '\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ userId: req.user.id
+ })
+ }
+
res.status(code).send(result)
}
}
@@ -118,22 +297,58 @@ router.postAsync('/:id/password', async (req, res) => {
const result = await authentication.changePassword(id, body.password, body.passwordCurrent)
const code = result.code
delete result.code
+
+ if (code === 200) {
+ log({
+ category: 'USER_EDIT_PASSWORD',
+ description: '[' + id + '] Password changed.',
+ userId: req.user.id
+ })
+ } else {
+ log({
+ category: 'ERROR_USER_EDIT_PASSWORD',
+ description: '[' + id + '] Password could not be changed. Code ' + code,
+ userId: req.user.id
+ })
+ }
res.status(code).send(result)
} else res.status(400).send({ error: 'PASSWORD_MISSING', message: 'This service requires the current and the new password.' })
})
// Function for deleting a single user
-router.delete('/:id/', (req, res) => {
- // Check if the user has the permission for chaning those userdata. Else return.
+router.deleteAsync('/:id/', async (req, res) => {
if (req.params.id !== 'current') {
- return res.status(500).end()
+ // Check if the user has the permission for changing those userdata. Else return.
+ // return res.status(500).end()
}
const id = req.params.id === 'current' ? req.user.id : req.params.id
-
+ const user = await db.user.findOne({ where: { id: id } })
// Every user can delete his own account.
- db.user.destroy({ where: { id } }).then(() => {
- res.status(200).end()
- })
+ const count = await db.user.destroy({ where: { id } })
+ if (count !== 1) {
+ log({
+ category: 'ERROR_USER_DELETE',
+ description: '[' + user.id + '] ' + user.username + ': User could not be deleted.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ user,
+ userId: req.user.id
+ })
+ } else {
+ log({
+ category: 'USER_DELETE',
+ description: '[' + user.id + '] ' + user.username + ': User successfully deleted.\n' +
+ 'ID: ' + user.id + '\n' +
+ 'Username: ' + user.username + '\n' +
+ 'Name: ' + user.name + '\n' +
+ 'E-Mail: ' + user.email + '\n',
+ user,
+ userId: req.params.id === 'current' ? undefined : req.user.id
+ })
+ }
+ res.status(200).end()
})
// ############################################################################