- /**
- * Helpers functions to handle user with MongoDB.
- * @module ./DBModels/userDBHelpers
- */
-
-let mongo;
-let bhcAuth;
-let ObjectID = require('mongodb').ObjectID;
-
-module.exports = (mongoInited, bhcAuth_inited) => {
-
- mongo = mongoInited;
- bhcAuth = bhcAuth_inited;
-
- return {
- __defaulter: defaulter,
- __defaulterUser: defaulterUser,
- checkToken: checkToken,
- getUserById: getUserById,
- createUser: createUser,
- addCaculInHistory: addCaculInHistory,
- updateUserById: updateUserById,
- getCalculs: getCalculs,
- getCalculsIds: getCalculsIds,
- getUsersSubscribed: getUsersSubscribed,
- isSubscribed: isSubscribed
- }
-}
-
-/**
- * Used to add the properties of def into the input JSON object without erasing them.
- * @param {JSON} input - JSON object to edit.
- * @param {JSON} def - Default properties to add.
- * @throws Will throw an error if the argument is different than a JSON.
- * @returns {{ ...def, ...input }}
- */
-function defaulter(input, def) {
- if (typeof input !== "object" || typeof def !== "object")
- throw new Error("parameters must be JSON");
- return ({ ...def, ...input });
-}
-
-/**
- * Used to create a generic formatted JSON object for an user.
- * Add :
- * <pre class="prettyprint"><code>{orga: "", history: [], subscribed: true, activated: false}</code></pre>
- * properties if they are not present in the input and set them to default value.
- * @param {JSON} input - JSON object to default.
- * @throws Will throw an error if the argument is different than a JSON.
- * @returns {Object} With default properties for an user : ``{orga:String, history:String[], subscribed:Boolean, activated:Boolean}``
- */
-function defaulterUser(input) {
- if (typeof input !== "object")
- throw new Error("input must be JSON");
- return (defaulter(input, {
- orga: "",
- history: [],
- subscribed: true,
- activated: false
- }));
-}
-
-/**
- * Check if a token is present in the Authorization header of the HTTP request and in the right format : ``Bearer <token>``.
- * @async
- * @param {Object} req - The HTTP request object received
- * @throws Will throw an error if :
- * - Authorization header is missing
- * - Token has a wrong format
- * - Token is invalid
- * @returns {string} Token
- */
-async function checkToken(req) {
- let token = null;
-
- // Check that a token is in the header under Authorization
- try {
- token = req.headers.authorization.split(" ")[1];
- } catch (e) {
- throw new Error("no token or bad format in header");
- }
-
- // Check from bhcAuth if token is valid
- try {
- await bhcAuth.auth.verify(token);
- } catch (e) {
- throw new Error(e);
- }
-
- return (token);
-}
-
-/**
- * Insert an user to MongoDB in the 'users' collection.
- * @param {string} userID - User's unique id (mongo.ObjectID).
- * @param {Object} [userInfo={}] - User's informations.
- * @throws Will reject if :
- * - userId is not a string
- * - userInfo is not an object
- * - Mongo insertOne failed (eg. user already exists)
- * @returns {Promise} Promise object represents the result of inserting. See {@link https://docs.mongodb.com/manual/reference/method/db.collection.insertOne/ db.collection.insertOne}.
- */
-function createUser(userID, userInfo = {}) {
- let prom = new Promise((resolve, reject) => {
- if (typeof userID !== "string")
- return reject("userId must be a string");
- if (typeof userInfo !== "object")
- return reject("userInfo must be JSON");
- let input = defaulterUser(userInfo);
- if (typeof input['orga'] !== "string" || typeof input['subscribed'] !== "boolean" || typeof input['activated'] !== "boolean" || !Array.isArray(input['history']))
- return reject("bad type for parameter in JSON");
- let id = mongo.parseID(userID);
- mongo.col("users").insertOne({ _id: id, ...input }, (err, res) => {
- if (err !== null) {
- return reject(err);
- }
- resolve(res);
- });
- });
- return (prom);
-}
-
-/**
- * Get an user in the database matching userID passed as parameter.
- * @param {string} userID - User's unique id (mongo.ObjectID).
- * @throws Will reject if :
- * - userId is not a string
- * - Mongo findOne failed (eg. user not found)
- * @returns {Promise} Promise object represents the result of finding.
- */
-function getUserById(UserId) {
- let prom = new Promise((resolve, reject) => {
- if (typeof UserId !== "string" && !(UserId instanceof ObjectID))
- return reject("UserId must be a string");
- let id = mongo.parseID(UserId);
- mongo.col("users").findOne({ _id: id }, (err, res) => {
- if (err !== null)
- return reject(err);
- if (res === null || res.length === 0)
- return reject("Could not find user with this id");
- resolve(res);
- });
- });
- return (prom);
-}
-/**
- * Add a calcul in the history of the user.
- * @async
- * @param {string} userId - User's unique id (mongo.ObjectID).
- * @param {string} calculId - Calcul's unique id (mongo.ObjectID).
- * @throws Throw an error if :
- * - Bad parameters (missing or wrong type)
- * - The calcul is already in the history of the user
- * - User with this userId does not exist
- * @returns {Promise} Returned by {@link module:./DBModels/userDBHelpers~updateUserById userDBHelpers.updateUserById()}.
- */
-async function addCaculInHistory(userId, calculId) {
- if (typeof userId === "undefined" || typeof calculId === "undefined") {
- throw new Error("function must have 2 parameters");
- }
- if ((typeof userId !== "string" && !(userId instanceof ObjectID)) || (typeof calculId !== "string" && !(calculId instanceof ObjectID))) {
- throw new Error("ID must be a string");
- }
- try {
- let history = (await getUserById(userId)).history;
- if (history.findIndex((e) => e === calculId ? true : false) === -1) {
- history.push(calculId);
- let res = await updateUserById(userId, { history: history });
- return (res);
- }
- throw "id of calcul is already in history for this user";
- } catch (e) {
- throw e;
- }
-}
-/**
- * Update the informations of an user.
- * @param {string} userId - User's unique id (mongo.ObjectID).
- * @param {Object} userInfo - User's informations.
- * @throws Will reject if :
- * - Bad parameter type
- * - Bad userInfo format
- * - Mongo findOneAndUpdate failed
- * - User with this id does not exist
- * @returns {Promise} Promise object represents the result of findOneAndUpdate.
- */
-function updateUserById(userId, userInfo) {
- let prom = new Promise((resolve, reject) => {
- if (typeof userId !== "string" && !(userId instanceof ObjectID)) {
- return reject("userId must be a string")
- }
- if (typeof userInfo !== "object") {
- return reject("userInfo must be a JSON");
- }
- if (JSON.stringify(userInfo) === JSON.stringify({})) {
- return reject("userInfo can't be empty");
- }
- if (typeof userInfo.orga !== "undefined") {
- typeof userInfo.orga !== "string" ? (() => { return reject("bad type for parameter orga in userInfo") })() : null;
- }
- if (typeof userInfo.history !== "undefined") {
- !Array.isArray(userInfo.history) ? (() => { return reject("bad type for parameter history in userInfo") })() : null;
- userInfo.history.forEach(function (calculInHistory) {
- typeof calculInHistory !== "string" && !(calculInHistory instanceof ObjectID) ? (() => { return reject("bad type for content of parameter history in userInfo") })() : null;
- });
- }
- if (typeof userInfo.subscribed !== "undefined") {
- typeof userInfo.subscribed !== "boolean" ? (() => { return reject("bad type for parameter subscribed in userInfo") })() : null;
- }
- if (typeof userInfo.activated !== "undefined") {
- typeof userInfo.activated !== "boolean" ? (() => { return reject("bad type for parameter activated in userInfo") })() : null;
- }
- let id = mongo.parseID(userId);
- mongo.col("users").findOneAndUpdate({ _id: id }, { $set: { ...userInfo } }, { returnOriginal: false }, (err, res) => {
- if (err !== null)
- return reject(err);
- if (res === null || res.length === 0 || res.value === null)
- return reject("Could not modify the user with this ID");
- resolve(res);
- });
- });
- return (prom);
-}
-
-//-----------------------------------------------------------------------------------------------------------------------------------
-// !!! non testée !!!
-//-----------------------------------------------------------------------------------------------------------------------------------
-
-
-function getCalculsIds(userId) {
- let prom = new Promise((resolve, reject) => {
- if (typeof userId !== "string" && !(userId instanceof ObjectID))
- return reject("UserId must be a string");
- let id = mongo.parseID(userId);
- mongo.col("users").findOne({ _id: id }, (err, res) => {
- if (err !== null) {
- return reject(err);
- }
- if (res === null || res.length === 0 || res.value === null) {
- return reject("Could not find calculs ids");
- }
- resolve(res.history);
- });
- });
- return (prom);
-}
-
-async function getCalculs(userId) {
- let prom = new Promise((resolve, reject) => {
- if (typeof userId !== "string" && !(userId instanceof ObjectID))
- return reject("UserId must be a string");
- let id = mongo.parseID(userId);
- try {
- console.log("getCalculsIds(id)", getCalculsIds(id));
- mongo.col("calculs").find({ _id: { $in: getCalculsIds(id) } }, (err, res) => {
- if (err !== null) {
- return reject(err);
- }
- //console.log("res : ", res);
- //res.hasNext() ? console.log("res.next :", await res.next()) : console.log("res havn't next");
- if (res.hasNext()) {
- console.log("res.next :", /*await */(res.next()));
- } else {
- console.log("res havn't next");
- }
- if (res === null || res.length === 0 /*|| res.value === null*/) {
- return reject("Could not find calculs");
- }
- resolve(res);
- });
- } catch (e) {
- return reject(e);
- }
- });
- return (prom);
-}
-
-
-async function isSubscribed(userId) {
- if (typeof userId === "undefined") {
- throw new Error("userId can't be empty");
- }
- if (typeof userId !== "string" && !(userId instanceof ObjectID)) {
- throw new Error("UserId must be a string");
- }
- let id = mongo.parseID(userId);
- let isSubscribed;
- let user;
- try {
- user = await getUserById(id);
- isSubscribed = user.subscribed;
- } catch (e) {
- throw new Error(e);
- }
- return (isSubscribed);
-}
-
-function getUsersSubscribed() {
- let prom = new Promise((resolve, reject) => {
- mongo.col("users").find({ _subsrcibed: true }, (err, res) => {
- if (err !== null) {
- return reject(err);
- }
- if (res === null || res.length === 0) {
- return reject("Could not find subscribed users");
- }
- resolve(res);
- });
- });
- return (prom);
-}
-
-