cpceed-webapp/api/users/user-manager.js
const userModels = require('api/users/user-models');
const User = userModels.User;
const Student = userModels.Student;
const Admin = userModels.Admin;
/**
* Callback for {@link createUser}
* @typedef {Object} CreateUserCallback
* @param {Object} err - The error.
* @param {string} id - The user UID.
*/
/**
* Given User information, create a User.
* @param {Object} data - The request body data.
* @param {String} data.role - The user role.
* @param {String} data.email - The user email address.
* @param {String} data.password - The user password.
* @param {String} data.name - The user name.
* @param {CreateUserCallback} next - The callback function to run after this function
* finishes.
*/
const createUser = (data, next) => {
// Ensure the required data is available.
if (!data) {
next({ err: 'Required parameters not found.' });
return;
}
// TODO(NilsG-S): Password validation
const info = {
email: data.email,
password: data.password,
name: data.name,
role: data.role,
};
let user;
if (data.role === 'student') {
// Create a student.
info.studentId = data.studentId;
user = new Student(info);
} else if (data.role === 'admin') {
// Create an admin.
user = new Admin(info);
} else {
next({ err: 'Valid role not found.' });
return;
}
User.findOne({ email: user.email }, (userErr, existingUser) => {
if (userErr) {
next(userErr);
} else if (existingUser) {
next({ err: 'Account with that email address already exists.' });
} else {
user.save((saveErr, dbUser) => {
next(saveErr, (dbUser || {}).id);
});
}
});
};
/**
* Callback for {@link modifyUser}
* @typedef {Object} ModifyUserCallback
* @param {Object} - The error
* @param {UserSchema} - The modified user object
*/
/**
* Updates the user with the passed in values.
* This method does NOT delete fields
* @param {string} userUid - The UID of the user to be updated
* @param {Object} reqData - The request data
* @param {Object} locals
* @param {ModifyUserCallback} modifyCallback
*/
const modifyUser = (userUid, reqData, locals, modifyCallback) => {
// TODO(NilsG-S): modifyUser cannot be used to modify email or password
const conditions = { _id: userUid };
const update = {};
Object.keys(reqData).forEach((key) => {
update[key] = reqData[key];
});
const options = { new: true };
Student.findOneAndUpdate(conditions, { $set: update }, options,
(err, results) => {
if (err) {
modifyCallback(err);
return;
}
const user = {
uid: results.id,
email: results.email,
name: results.name,
role: results.role,
};
if (user.role === 'student') {
user.points = results.points;
user.isApproved = results.isApproved;
}
modifyCallback(err, user);
});
};
/**
* Callback for {@link deleteUser}
* @typedef {Object} DeleteUserCallback
* @param {Object} - error
*/
/**
* Deletes the user from the database.
* @param {string} userUid - The UID of the user to be updated.
* @param {Object} locals
* @param {DeleteUserCallback} deleteCallback
*/
const deleteUser = (userUid, locals, deleteCallback) => {
User.findOneAndRemove({ _id: userUid }, deleteCallback);
};
/**
* Callback for {@link getUserById}
* @typedef {Object} GetUserCallback
* @param {Object} - error
* @param {UserSchemas} - Retrieved user
*/
/**
* Retrieves the user.
* @param {string} userUid - The UID of the user to be updated
* @param {Object} locals
* @param {GetUserCallback} queryCallback
*/
const getUserById = (userUid, locals, queryCallback) => {
User.findById(userUid, (err, results) => {
if (err) {
queryCallback(err);
return;
}
const user = {
uid: results.id,
email: results.email,
name: results.name,
role: results.role,
};
if (user.role === 'student') {
user.points = results.points;
user.isApproved = results.isApproved;
}
queryCallback(err, user);
});
};
module.exports = { createUser, modifyUser, deleteUser, getUserById };