Archived
2
This repository has been archived on 2023-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
definma-api/src/routes/user.ts

153 lines
5.4 KiB
TypeScript
Raw Normal View History

import express from 'express';
import mongoose from 'mongoose';
import bcrypt from 'bcryptjs';
import UserValidate from './validate/user';
import UserModel from '../models/user';
2020-04-23 17:46:00 +02:00
import mail from '../helpers/mail';
const router = express.Router();
router.get('/users', (req, res) => {
2020-04-24 12:25:32 +02:00
if (!req.auth(res, ['admin'], 'basic')) return;
UserModel.find({}).lean().exec( (err, data:any) => {
res.json(data.map(e => UserValidate.output(e)).filter(e => e !== null)); // validate all and filter null values from validation errors
});
});
2020-04-27 14:26:51 +02:00
router.get('/user:username([/](?!key|new).?*|/?)', (req, res, next) => { // this path matches /user, /user/ and /user/xxx, but not /user/key or user/new. See https://forbeslindesay.github.io/express-route-tester/ for the generated regex
req.params.username = req.params[0];
2020-04-24 12:25:32 +02:00
if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'basic')) return;
let username = req.authDetails.username;
if (req.params.username !== undefined) {
if (!req.auth(res, ['admin'], 'basic')) return;
username = req.params.username;
}
UserModel.findOne({name: username}).lean().exec( (err, data:any) => {
2020-04-24 17:36:39 +02:00
if (err) next(err);
if (data) {
res.json(UserValidate.output(data)); // validate all and filter null values from validation errors
}
else {
res.status(404).json({status: 'Not found'});
}
2020-04-24 12:25:32 +02:00
});
});
2020-04-27 14:26:51 +02:00
router.put('/user:username([/](?!key|new).?*|/?)', (req, res, next) => { // this path matches /user, /user/ and /user/xxx, but not /user/key or user/new
2020-04-24 17:36:39 +02:00
console.log(req.authDetails);
if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'basic')) return;
let username = req.authDetails.username;
if (req.params.username !== undefined) {
if (!req.auth(res, ['admin'], 'basic')) return;
username = req.params.username;
}
const {error, value: user} = UserValidate.input(req.body, 'change' + (req.authDetails.level === 'admin'? 'admin' : ''));
console.log(error);
console.log(user);
if(error !== undefined) {
res.status(400).json({status: 'Invalid body format'});
return;
}
if (user.hasOwnProperty('pass')) {
user.pass = bcrypt.hashSync(user.pass, 10);
}
// check that user does not already exist if new name was specified
if (user.hasOwnProperty('name') && user.name !== username) {
UserModel.find({name: user.name}).lean().exec( (err, data:any) => {
if (err) next(err);
if (data.length > 0) {
res.status(400).json({status: 'Username already taken'});
return;
}
UserModel.findOneAndUpdate({name: username}, user, {new: true}).lean().exec( (err, data:any) => {
if (err) next(err);
if (data) {
res.json(UserValidate.output(data)); // validate all and filter null values from validation errors
}
else {
res.status(404).json({status: 'Not found'});
}
});
});
}
else {
UserModel.findOneAndUpdate({name: username}, user, {new: true}).lean().exec( (err, data:any) => {
if (err) next(err);
if (data) {
res.json(UserValidate.output(data)); // validate all and filter null values from validation errors
}
else {
res.status(404).json({status: 'Not found'});
}
});
}
});
2020-04-27 14:26:51 +02:00
router.get('/user/key', (req, res, next) => {
console.log('hmm');
if (!req.auth(res, ['read', 'write', 'maintain', 'dev', 'admin'], 'basic')) return;
UserModel.findOne({name: req.authDetails.username}).lean().exec( (err, data:any) => {
if (err) next(err);
res.json({key: data.key});
});
});
router.post('/user/new', (req, res, next) => {
2020-04-23 13:59:45 +02:00
if (!req.auth(res, ['admin'], 'basic')) return;
// validate input
2020-04-24 17:36:39 +02:00
const {error, value: user} = UserValidate.input(req.body, 'new');
if(error !== undefined) {
res.status(400).json({status: 'Invalid body format'});
return;
}
2020-04-22 17:38:24 +02:00
// check that user does not already exist
2020-04-24 12:25:32 +02:00
UserModel.find({name: user.name}).lean().exec( (err, data:any) => {
2020-04-22 17:38:24 +02:00
if (err) next(err);
if (data.length > 0) {
res.status(400).json({status: 'Username already taken'});
return;
}
user.key = mongoose.Types.ObjectId(); // use object id as unique API key
bcrypt.hash(user.pass, 10, (err, hash) => { // password hashing
user.pass = hash;
new UserModel(user).save((err, data) => { // store user
if (err) next(err);
res.json(UserValidate.output(data.toObject()));
});
});
});
});
2020-04-23 17:46:00 +02:00
router.post('/user/passreset', (req, res, next) => {
// check if user/email combo exists
UserModel.find({name: req.body.name, email: req.body.email}).lean().exec( (err, data: any) => {
2020-04-23 17:46:00 +02:00
if (err) next(err);
if (data.length === 1) { // it exists
const newPass = Math.random().toString(36).substring(2);
bcrypt.hash(newPass, 10, (err, hash) => { // password hashing
if (err) next(err);
UserModel.findByIdAndUpdate(data[0]._id, {pass: hash}, err => { // write new password
2020-04-23 17:46:00 +02:00
if (err) next(err);
mail(data[0].email, 'Your new password for the DFOP database', 'Hi, <br><br> You requested to reset your password.<br>Your new password is:<br><br>' + newPass + '<br><br>If you did not request a password reset, talk to the sysadmin quickly!<br><br>Have a nice day.<br><br>The DFOP team', err => {
if (err) next(err);
res.json({status: 'OK'});
});
});
});
}
else {
res.status(404).json({status: 'Not found'});
}
});
});
module.exports = router;