summaryrefslogblamecommitdiffstats
path: root/server/api/users.js
blob: 744ffc663ff6df8bfeb5c04ce57bcc0f9480e544 (plain) (tree)
1
2
3
4
5
6
7
                     
                          
                                                         


                                                   
                                                                          







                                                                               
                                                                                                                              







                                                                      
                                                                                              
             
                              

                         
   




                                                                               
                                          
                                                    

                                                                                            












                                                                         
 
                                               
                                                     
                       



                                                                  
                                                                       

                                                                    


                                    



                                                    
          


                                                                        
                                                                                                                                                         





                                                       
                        



                                                        
                                  
                                                    
                                                                                                                                                                                            

                                                
                                                                                                      
                                                                                                                                   




                                    




                                                                                                   
       
     
                         
   


                                          
                                                       

                          
                                






                                                                                                                                                                                   

  
                                      












                                                                                  

                                                                               
 
                              
/* global __appdir */
var path = require('path')
var db = require(path.join(__appdir, 'lib', 'sequelize'))
var express = require('express')
const { decorateApp } = require('@awaitjs/express')
var router = decorateApp(express.Router())
var authentication = require(path.join(__appdir, 'lib', 'authentication'))

// ############################################################################
// ###########################  GET requests  #################################

/*
 * @return: Returns a list of all users in the database and their given roles.
 */
router.getAsync('', async (req, res) => {
  const users = await db.user.findAll({ attributes: { exclude: ['password'] }, include: ['roles'], order: [['name', 'ASC']] })
  res.status(200).send(users)
})

/*
 * @return: Returns information about a specific user.
 */
router.getAsync('/:id', async (req, res) => {
  const id = req.params.id === 'current' ? req.user.id : req.params.id
  const user = await db.user.findOne({ where: { id }, attributes: { exclude: ['password'] } })
  if (user) {
    res.status(200).send(user)
  } else {
    res.status(404).end()
  }
})

// ############################################################################
// ##########################  POST requests  #################################

// Post request for adding roles to users.
router.postAsync('/:id/roles', async (req, res) => {
  if (!await req.user.hasPermission('permissions.grantrevoke')) return res.status(403).end()

  const id = req.params.id === 'current' ? req.user.id : req.params.id
  const user = await db.user.findOne({ where: { id } })
  if (user) {
    if (req.query.delete !== undefined && req.query.delete !== 'false') {
      await user.removeRoles(req.body.ids)
    } else {
      await user.addRoles(req.body.ids)
    }
    res.status(200).end()
  } else {
    res.status(404).end()
  }
})

// Post request for creating new user accounts.
router.postAsync(['/', '/:id'], async (req, res) => {
  const body = req.body
  if (req.params.id !== 'current') {
    // TODO: Check for permission to delete / create / update user
  }

  if (req.query.delete !== undefined && req.query.delete !== 'false') {
    const count = await db.user.destroy({ where: { id: body.ids } })
    return res.send({ count })
  }

  if (req.params.id === undefined) {
    const result = await authentication.signup(body)
    const code = result.code
    delete result.code
    return res.status(code).send(result)
  } else {
    const id = req.params.id === 'current' ? req.user.id : req.params.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 (user) {
      let userinfo = {
        name: body.name,
        email: email
      }

      // 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)' })

        // 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.' })
        userinfo.username = username
      }

      // Update the user.
      await user.update(userinfo)
      if (body.password) {
        const result = await authentication.changePassword(id, body.password, body.passwordCurrent)
        const code = result.code
        delete result.code
        res.status(code).send(result)
      }
    }
    res.status(200).end()
  }
})

// Post request for changing the password.
router.postAsync('/:id/password', async (req, res) => {
  const id = req.params.id
  const body = req.body
  // Check if passwords are set.
  if (body.passwordCurrent && body.password) {
    if (body.passwordCurrent === body.password) return res.status(500).send({ error: 'PASSWORD_ERROR', message: 'The provided password must be different than the old password.' })
    const result = await authentication.changePassword(id, body.password, body.passwordCurrent)
    const code = result.code
    delete result.code
    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.
  if (req.params.id !== 'current') {
    return res.status(500).end()
  }
  const id = req.params.id === 'current' ? req.user.id : req.params.id

  // Every user can delete his own account.
  db.user.destroy({ where: { id } }).then(() => {
    res.status(200).end()
  })
})

// ############################################################################
// ############################################################################

module.exports.router = router