Select Git revision
Embruch, Gerd authored
added mongoose, changed users controller & routes, added error handling route, changed customError, too much not finished yet
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
User.js 6.50 KiB
import User from "../models/User.js";
import { createRecord, findOneRecord } from "../utils/handleDB.js";
import { CustomError } from "../utils/handleErrors.js";
import { prefillDocumentObject, hideConfidentialFields } from '../utils/handleSchemes.js';
import { unlinkSync } from 'fs';
import { createVerificationToken } from "../utils/handleTokens.js";
import { sendEmail } from "../utils/handleMailer.js";
/** *******************************************************
* CREATE ONE
*/
export const createUser = async (req, res, next) => {
try {
// create user object
req.document = await createRecord(User, prefillDocumentObject(User, req.body));
next();
// on error
} catch (error) {
next(error);
}
};
/** *******************************************************
* SEND VERIFICATION MAIL
*/
export const sendVerificationEmail = async (req, res, next) => {
try {
// create verification token
const verificationToken = createVerificationToken(req.document);
let subject = "[RagChat] Account Verification";
let to = req.document.email;
let link = `${process.env.FRONTEND_URL}/reset_password/${verificationToken}/${req.document._id}`;
let html = `<p>Hi<p><br><p>Please click on the following <a href="${link}">link</a> to process the password reset. This Token is valid for ${process.env.PASSWORD_TOKEN_TTL}.</p>
${verificationToken}
<br><p>If you did not request this, please ignore this email.</p>`;
await sendEmail({ to, subject, html });
// return msg
return res.status(201).json({ message: 'Check your emails for the verification link.' });
} catch (error) {
next(error);
}
};
/** *******************************************************
* FIND USER BY MAIL
*/
export const prefetchUserByEmail = async (req, res, next) => {
try {
// search for matching document
const foundUser = await findOneRecord(User, { email: req.body.email });
if (!foundUser) {
return res.status(201).json({ message: 'Check your emails for the verification link.' });
}
req.document = foundUser;
next();
} catch (error) {
next(error);
}
};
/**
* ################################## UNTESTED BELOW ##################################
*/
/** *******************************************************
* GET ONE
*/
export const getUser = (req, res) => {
return res.json(req.requestedDocument);
};
/** *******************************************************
* GET MULTIPLE
*/
export const getUsers = async (req, res) => {
try {
// FIX Mongoose .populate() für createdBy & updatedBy (updatedBy wird bei Update überschrieben und ist nicht länger populated)
const users = await User.find().populate('createdBy').populate('updatedBy');
return res.json(users);
} catch (error) {
next(error);
}
};
/** *******************************************************
* GET SCHEMA
*/
export const getSchema = async (req, res) => {
return res.json(User.schema.paths);
};
/** *******************************************************
* UPDATE ONE
*/
export const updateUser = async (req, res, next) => {
// check if user is allowed to change data
// if not self editing
if (global.currentUserId !== req.requestedDocument.id) {
// check for current users role
if (!(global.currentUserRole >= 2)) return customError(res, '', 405);
}
// filter req data by schema field names
const newData = prefillDocumentObject(User, req.body);
// drop password if empty to prevent setting empty
if (!newData.password) delete newData.password;
// merge new data into document
Object.assign(req.requestedDocument, newData);
// try saving
try {
const updatedUser = await req.requestedDocument.save({ new: true });
const document = hideConfidentialFields(User, updatedUser);
// return msg incl. document
res.json({ message: 'User successfully updated', document });
} catch (error) {
next(error);
}
};
/** *******************************************************
* DELETE AVATAR
*/
export const deleteAvatar = async (req, res) => {
// check if user is allowed to change data
// if not self editing
if (global.currentUserId !== req.requestedDocument.id) {
// check for current users role
if (!(global.currentUserRole >= 2)) return customError(res, '', 405);
}
// drop file
if (req.requestedDocument.avatar.path) {
try {
unlinkSync(req.requestedDocument.avatar.path);
} catch (error) {
next(error);
}
}
// drop avatar info
if (req.requestedDocument.avatar) {
req.requestedDocument.avatar = undefined;
}
// try saving
try {
const updatedUser = await req.requestedDocument.save({ new: true });
const document = hideConfidentialFields(User, updatedUser._doc);
// return msg incl. document
res.json({ message: 'Avatar successfully deleted', document });
} catch (error) {
next(error);
};
};
/** *******************************************************
* DELETE ONE
*/
export const deleteUser = async (req, res) => {
// check if user is allowed to change data
// if not self editing
if (global.currentUserId !== req.requestedDocument.id) {
// check for current users role
if (!(global.currentUserRole >= 2)) return customError(res, '', 405);
}
try {
// delete document
const document = await req.requestedDocument.delete();
// return msg incl. document
return res.status(200).json({ message: 'User successfully deleted', document: req.requestedDocument });
} catch (error) {
next(error);
}
};
// *******************************************************
// FUNCTIONS
/**
* get a document based on ID from request param
* save this to req.requestedDocument for further computing
*
* @param req request data
* @param res response, sended to the user
* @param next simply tell the code to go on with next function
*
*/
export const prefetchUser = async (req, res, next) => {
try {
if (!req.params.id) return res.status(400).json({ message: 'No ID given' });
// search for matching document
// FIX Mongoose .populate() für createdBy & updatedBy (updatedBy wird bei Update überschrieben und ist nicht länger populated)
const user = await User.findById(req.params.id).populate('createdBy').populate('updatedBy');
// if no matching document was found
if (!user._id) return res.status(404).json({ message: 'Cannot find user' });
// remember document in res
req.requestedDocument = user;
// going on with the rest of the code
next();
} catch (error) {
// on error
next(error);
}
};