From 447438a5610c371ba75a97a1143fa9cf65177c6e Mon Sep 17 00:00:00 2001 From: Dunsin Date: Mon, 12 Aug 2024 13:09:12 +0100 Subject: [PATCH] refactor: combine activeUser and User to one collection --- server/controllers/userController.js | 19 +++-- server/models/ChatModel.js | 2 +- server/models/MessageModel.js | 8 +- .../{ActiveUserModel.js => UserModel.js} | 42 ++++++++-- server/models/UserSchema.js | 42 ---------- server/utils/helper.js | 8 +- server/utils/lib.js | 77 ++++++++++++------- 7 files changed, 109 insertions(+), 89 deletions(-) rename server/models/{ActiveUserModel.js => UserModel.js} (50%) delete mode 100644 server/models/UserSchema.js diff --git a/server/controllers/userController.js b/server/controllers/userController.js index 4ffcdde8..6e5164af 100644 --- a/server/controllers/userController.js +++ b/server/controllers/userController.js @@ -1,15 +1,15 @@ /* eslint-disable camelcase */ const UserRouter = require('express').Router(); -const { v4: uuidv4 } = require('uuid'); +const { ObjectId } = require('mongodb'); const multer = require('multer'); // multer for profile image const storage = multer.memoryStorage(); const imageUpload = multer({ storage: storage }); -const User = require('../models/UserSchema'); -const { emailValidator } = require('../utils/helper'); +const User = require('../models/UserModel'); +const { emailValidator, generateObjectId } = require('../utils/helper'); const { OK, @@ -19,12 +19,21 @@ const { } = require('../httpStatusCodes.js'); const createUserWithAutoId = async (email) => { + const id = generateObjectId(); // Logic to create a new user with an autogenerated ID - return User.create({ _id: uuidv4(), email }); + return User.create({ + _id: new ObjectId(id), + email, + loginId: id, + }); }; const createUserWithId = async (email, id) => { - return User.create({ _id: id, email }); + return User.create({ + _id: new ObjectId(id), + email, + loginId: id, + }); }; const loginUser = async (req, res) => { diff --git a/server/models/ChatModel.js b/server/models/ChatModel.js index b44a21bc..d82897f2 100644 --- a/server/models/ChatModel.js +++ b/server/models/ChatModel.js @@ -8,7 +8,7 @@ const ChatSchema = new Schema( users: [ { type: Schema.Types.ObjectId, - ref: 'ActiveUser', + ref: 'User', }, ], messages: [ diff --git a/server/models/MessageModel.js b/server/models/MessageModel.js index 4430299d..5ebdfbb1 100644 --- a/server/models/MessageModel.js +++ b/server/models/MessageModel.js @@ -23,7 +23,7 @@ const MessageSchema = new Schema( sender: { type: Schema.Types.ObjectId, required: true, - ref: 'ActiveUser', + ref: 'User', }, type: { type: String, @@ -35,8 +35,8 @@ const MessageSchema = new Schema( }, replyTo: { type: Schema.Types.ObjectId, - ref: 'Message' - } + ref: 'Message', + }, }, { timestamps: true, @@ -53,7 +53,7 @@ const MessageSchema = new Schema( containsBadword: this.containsBadword, oldMessages: this.oldMessages, isRead: this.isRead, - replyTo: this.replyTo?.toString() || null + replyTo: this.replyTo?.toString() || null, }; }, }, diff --git a/server/models/ActiveUserModel.js b/server/models/UserModel.js similarity index 50% rename from server/models/ActiveUserModel.js rename to server/models/UserModel.js index f82bb266..4767d615 100644 --- a/server/models/ActiveUserModel.js +++ b/server/models/UserModel.js @@ -1,13 +1,33 @@ const mongoose = require('mongoose'); -const { model, Schema } = mongoose; +const { Schema, model } = mongoose; -const Chat = require('./ChatModel'); - -const ActiveUserSchema = new Schema( +const UserSchema = new Schema( { + _id: { + type: String, + }, email: { - type: Schema.Types.Mixed, - default: null, + type: String, + }, + gender: { + type: String, + enum: ['Male', 'Female', 'Unknown'], + }, + age: { + type: Number, + }, + username: { + type: String, + default: 'Anonymous', + }, + aboutMe: { + type: String, + }, + settings: { + type: Object, + }, + profileImage: { + type: String, }, loginId: { type: String, @@ -31,6 +51,12 @@ const ActiveUserSchema = new Schema( return { id: this._id.toString(), email: this.email || null, + gender: this.gender, + age: this.age, + username: this.username, + aboutMe: this.aboutMe || null, + settings: this.settings || {}, + profileImage: this.profileImage || null, loginId: this.loginId, emailOrLoginId: this.emailOrLoginId, socketConnections: [], @@ -44,4 +70,6 @@ const ActiveUserSchema = new Schema( } ); -module.exports = model('ActiveUser', ActiveUserSchema); +UserSchema.index({ loginId: 1 }, { unique: true }); + +module.exports = model('User', UserSchema); diff --git a/server/models/UserSchema.js b/server/models/UserSchema.js deleted file mode 100644 index 2a8ec35a..00000000 --- a/server/models/UserSchema.js +++ /dev/null @@ -1,42 +0,0 @@ -const mongoose = require('mongoose'); - -// User schema -const UserSchema = new mongoose.Schema({ - _id: String, - email: { - type: String, - required: true, - }, - gender: { - type: String, - enum: ['Male', 'Female', 'Unknown'], - required: false, - default: 'Unknown', - }, - age: { - type: Number, - required: false, - default: null, - }, - username: { - type: String, - required: false, - default: 'Anonymous', - }, - aboutMe: { - type: String, - required: false, - }, - settings: { - type: Object, - required: false, - }, - profileImage: { - type: String, - required: false - }, -}); - -UserSchema.index({ email: 1 }, { unique: true }); - -module.exports = mongoose.model('User', UserSchema); diff --git a/server/utils/helper.js b/server/utils/helper.js index 437ede76..bf9b84e6 100644 --- a/server/utils/helper.js +++ b/server/utils/helper.js @@ -1,3 +1,5 @@ +const crypto = require('crypto'); + // Defining separate email validation middleware const validator = require('validator').default; const emailValidator = (req, res, next) => { @@ -12,7 +14,11 @@ const emailValidator = (req, res, next) => { } }; +function generateObjectId() { + return crypto.randomBytes(12).toString('hex'); +} + module.exports = { emailValidator, + generateObjectId, }; - diff --git a/server/utils/lib.js b/server/utils/lib.js index 6c0fce11..eee78488 100644 --- a/server/utils/lib.js +++ b/server/utils/lib.js @@ -1,11 +1,12 @@ const { Socket } = require('socket.io'); const mongoose = require('mongoose'); const CryptoJS = require('crypto-js'); +const { ObjectId } = require('mongodb'); -const ActiveUser = require('../models/ActiveUserModel'); +const ActiveUser = require('../models/UserModel'); const Chat = require('../models/ChatModel'); const Message = require('../models/MessageModel'); - +const { generateObjectId } = require('./helper'); /** * @typedef {{ @@ -127,9 +128,11 @@ function getChatsCount(emailOrLoginId) { */ async function delActiveUser(user) { delete activeUsers[user.emailOrLoginId]; - await ActiveUser.deleteOne({ - _id: user.id, - }); + + const userToDelete = await ActiveUser.findById(user.id); + if (!userToDelete.email) { + await ActiveUser.deleteOne({ _id: user.id }); + } } // This funtion is used for removing user from waiting list @@ -192,38 +195,54 @@ async function createChat(users) { const chatId = _chat._id.toString(); - // this shouldn't happen as now new users are added to active users collection instead of users collection. + // this shouldn't happen as now new users are added to active + // users collection instead of users collection. // find a way to take users from users and fill it in active users. - for (let i = 0; i < users.length; i++) { - const { email, loginId } = users[i]; - const user = await ActiveUser.create({ - email, - loginId, - currentChat: _chat._id, - }); - _chat.users.push(user._id); + try { + for (let i = 0; i < users.length; i++) { + const { email, loginId } = users[i]; + let user; + const findUser = await ActiveUser.findOne({ loginId: loginId }); + if (findUser) { + user = findUser; + } else { + user = await ActiveUser.create({ + email, + loginId, + currentChat: _chat._id, + _id: new ObjectId(generateObjectId()), + }); + } + _chat.users.push(user._id); - users[i].id = user._id.toString(); - users[i].currentChatId = chatId; - users[i].chatIds.push(chatId); + users[i].id = user._id.toString(); + users[i].currentChatId = chatId; + users[i].chatIds.push(chatId); - users[i].socketConnections.map((socket) => { - socket.join(chatId); - }); + users[i].socketConnections.map((socket) => { + socket.join(chatId); + }); - addActiveUser(users[i]); + addActiveUser(users[i]); + } + } catch (error) { + console.log(`error creating user: ${error}`); } - const chat = await Chat.create(_chat); - /** @type {Chat} */ - const optimizedChat = { - ...chat.optimizedVersion, - userIds: users.map((user) => user.emailOrLoginId), - }; + try { + const chat = await Chat.create(_chat); + /** @type {Chat} */ + const optimizedChat = { + ...chat.optimizedVersion, + userIds: users.map((user) => user.emailOrLoginId), + }; - chats[chatId] = optimizedChat; + chats[chatId] = optimizedChat; - return optimizedChat; + return optimizedChat; + } catch (error) { + console.log(`error creating chat: ${error}`); + } } /**