Skip to content
Snippets Groups Projects
Select Git revision
  • 6ce17d05538858e86a0853822f121a497b5a6246
  • main default protected
2 results

lecture_1.ipynb

Blame
  • 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);
      }
    };