Skip to content
Snippets Groups Projects
Select Git revision
  • 2a362bff8aa527c358d01ff1f835acd1ae31113e
  • main default protected
  • editUser
  • loadTests
  • fixTests
  • userhandling
  • updateEmbeddings
  • addRAGSources
  • testing
  • conversations
  • inputValidation
  • rag
  • chatting
  • userauth
14 results

User.js

Blame
  • Embruch, Gerd's avatar
    Embruch, Gerd authored
    added mongoose, changed users controller & routes, added error handling route, changed customError, too much not finished yet
    2a362bff
    History
    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);
      }
    };