From f34f53d80699390ee726f7f2b1fab273283d8bda Mon Sep 17 00:00:00 2001 From: Goutham Date: Tue, 18 Apr 2023 17:39:19 +0530 Subject: [PATCH 01/20] Implemented hashing and dehashing while signup and sign in with bcrypt js.. --- models/user.js | 9 +++++++-- package-lock.json | 6 ++++++ package.json | 1 + util.js | 26 +++++++++++++++++++++++++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/models/user.js b/models/user.js index 43f2596..3500339 100644 --- a/models/user.js +++ b/models/user.js @@ -1,5 +1,5 @@ const {connector} = require('./databaseUtil'); - +const {hashPassword,comparePasswords} = require("../util"); const userSchema = { name: {type: String, required: true}, emailId: {type: String, unique: true, required: true}, @@ -19,6 +19,11 @@ async function createUser(name, password, emailId, uid, userType){ uid: uid, userType: userType }); + + //hash the password + const hashedPassword = await hashPassword(user.password); + user.password = hashedPassword; + let newUser = {}; await user.save().then((savedUser) => { newUser = savedUser ; @@ -30,7 +35,7 @@ async function createUser(name, password, emailId, uid, userType){ async function validateUser(uid, pass){ let user = await User.findOne({uid: uid}).catch(err=>console.log(err)) if(user){ - if(user.password==pass) + if(comparePasswords(pass,user.password)) return user return null; } diff --git a/package-lock.json b/package-lock.json index c92248e..1d92d15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "api", "version": "0.0.0", "dependencies": { + "bcryptjs": "^2.4.3", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", @@ -1170,6 +1171,11 @@ "node": ">= 0.8" } }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", diff --git a/package.json b/package.json index ff388e7..0663b75 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "serverstartWin": "SET DEBUG=api:* && npm run devstart" }, "dependencies": { + "bcryptjs": "^2.4.3", "cookie-parser": "~1.4.4", "cors": "^2.8.5", "debug": "~2.6.9", diff --git a/util.js b/util.js index 43e8674..086b793 100644 --- a/util.js +++ b/util.js @@ -1,9 +1,33 @@ const jwt = require("jsonwebtoken"); - +const bcrypt = require("bcryptjs"); exports.genrateToken = (data)=>{ return jwt.sign(data, process.env.TOKEN_SECRET); } +exports.hashPassword = async(password) =>{ + try { + const salt = await bcrypt.genSalt(10); + const hashedPassword = await bcrypt.hash(password,salt); + return hashedPassword; + } catch (error) { + return error.message; + } +} + +exports.comparePasswords = async(userPassword,storedPassword) =>{ + try { + bcrypt.compare(userPassword,storedPassword,(err,success)=>{ + if(err) throw Error(); + if(success){ + return true; + } + else return false; + }) + } catch (error) { + return error.message; + } +} + /** * * @param {*} data any data that you want as return from the function after mentioned time From 0e0e4019cb541cc9bcf11d0e024d9ec49b10f43e Mon Sep 17 00:00:00 2001 From: Aastha Rai Date: Wed, 14 Jun 2023 09:02:55 +0530 Subject: [PATCH 02/20] created attendance.js and attendanceSchema in it --- models/attendance.js | 11 +++++++++++ models/user.js | 1 - 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 models/attendance.js diff --git a/models/attendance.js b/models/attendance.js new file mode 100644 index 0000000..59b693b --- /dev/null +++ b/models/attendance.js @@ -0,0 +1,11 @@ +import connector from "./databaseUtil"; + +connector.set("debug", true); + +const attendanceSchema = { + date: { type: Date, required: true }, + time: { type: String, required: true }, + class: { type: connector.Schema.Types.ObjectId, ref: "Infrastructure" }, +}; + +const Attendance = connector.model("Attendance", attendanceSchema); diff --git a/models/user.js b/models/user.js index eb051db..ca13c10 100644 --- a/models/user.js +++ b/models/user.js @@ -1,5 +1,4 @@ import connector from "#models/databaseUtil"; -import { logger } from "#util"; connector.set("debug", true); const userSchema = { From b9407ff85e03a06f57f4e80f4b1dc7cf3ca4f7c0 Mon Sep 17 00:00:00 2001 From: Aastha Rai Date: Wed, 14 Jun 2023 09:15:59 +0530 Subject: [PATCH 03/20] #56 updated Schema and export in attendance.js --- models/attendance.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/models/attendance.js b/models/attendance.js index 59b693b..9ea57d2 100644 --- a/models/attendance.js +++ b/models/attendance.js @@ -1,11 +1,15 @@ import connector from "./databaseUtil"; - +import Infrastructure from "./infrastructure"; connector.set("debug", true); const attendanceSchema = { date: { type: Date, required: true }, time: { type: String, required: true }, - class: { type: connector.Schema.Types.ObjectId, ref: "Infrastructure" }, + class: Infrastructure, }; const Attendance = connector.model("Attendance", attendanceSchema); + +export default { + Attendance, +}; From 90f5852b6a5e55d670d18110b845be747b36b638 Mon Sep 17 00:00:00 2001 From: Aastha Rai Date: Wed, 14 Jun 2023 15:52:22 +0530 Subject: [PATCH 04/20] #71 CRUD operation for attendance model --- models/attendance.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/models/attendance.js b/models/attendance.js index 9ea57d2..d5ced3c 100644 --- a/models/attendance.js +++ b/models/attendance.js @@ -1,15 +1,37 @@ import connector from "./databaseUtil"; import Infrastructure from "./infrastructure"; + connector.set("debug", true); const attendanceSchema = { date: { type: Date, required: true }, time: { type: String, required: true }, + absentees: { type: Array }, class: Infrastructure, }; const Attendance = connector.model("Attendance", attendanceSchema); +async function create(date, time, absentees) { + const attendance = new Attendance({ + date, + time, + absentees, + }); + const newAttendence = await attendance.save(); + return newAttendence; +} + +async function remove(filter) { + const res = await Attendance.findOneAndDelete(filter); + return res; +} + +async function grantAttendance(roll, date) { + const res = await Attendance.findOneAndUpdate(date, {$pull: { absentees: roll } }, { new: true }); + return res; +} + export default { - Attendance, -}; + create, remove, grantAttendance, +}; \ No newline at end of file From 75c2ebd29b9f5ae4f8d902ab7a151fad86850d48 Mon Sep 17 00:00:00 2001 From: Ankit <115006624+ANKIT638-ux@users.noreply.github.com> Date: Wed, 14 Jun 2023 23:32:34 +0530 Subject: [PATCH 05/20] create subject model --- models/subject.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 models/subject.js diff --git a/models/subject.js b/models/subject.js new file mode 100644 index 0000000..8135139 --- /dev/null +++ b/models/subject.js @@ -0,0 +1,27 @@ +const { connector } = require("#models/databaseUtil"); +const { Module } = require("#models/module"); +const { Practical} = require("#models/practical"); + +const subjectcontentSchema = { + courseCode: {type: String, required: true}, + courseName: {type: String, required: true}, + totalCredit: {type: Number, required: true}, + duration: {type: Number, required: true}, + subID: {type: String, required: true}, + subName: {type:String, required: true}, + semester: {type: String, required: true}, + ltpCredDist: {type: [Number], required: true}, + subType: {type: String, enum: ["open", "professional", "core"], required: true}, // can be open, professional, or core + prerequisites: {type: String, required: true}, + courseObjective:{type: String, required: true}, + courseOutcomes : [{courseOutcome:{type: String}, RBTLevel: {type:String}}], //this is the modules from syllabus + modules: {type: [Module], required: true}, + reccTextbooks: {type: [String], required: true}, + refBooks: {type: [String], required: true}, + evalScheme: {type: String[Number], required: true}, + maxMarks: {type: Number, required: true}, + practicals: {type: [Practical], required: true} +}; + +const subjectcontentModel = new connector.model("subjectcontent", subjectcontentSchema); +module.export = {} From ae1f7d4cf7cc8798eba43888120929bea54b8fef Mon Sep 17 00:00:00 2001 From: Ankit <115006624+ANKIT638-ux@users.noreply.github.com> Date: Thu, 15 Jun 2023 09:55:09 +0530 Subject: [PATCH 06/20] 58-create_subject_model_1 --- models/subject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/subject.js b/models/subject.js index 8135139..97baeb9 100644 --- a/models/subject.js +++ b/models/subject.js @@ -18,7 +18,7 @@ const subjectcontentSchema = { modules: {type: [Module], required: true}, reccTextbooks: {type: [String], required: true}, refBooks: {type: [String], required: true}, - evalScheme: {type: String[Number], required: true}, + evalScheme: {type: [Number], required: true}, maxMarks: {type: Number, required: true}, practicals: {type: [Practical], required: true} }; From d536f470594b505484550fda80dc834facd54283 Mon Sep 17 00:00:00 2001 From: Ankit <115006624+ANKIT638-ux@users.noreply.github.com> Date: Thu, 15 Jun 2023 15:46:01 +0530 Subject: [PATCH 07/20] 58 Create subject model2 --- models/subject.js | 1 - 1 file changed, 1 deletion(-) diff --git a/models/subject.js b/models/subject.js index 97baeb9..31b5fbf 100644 --- a/models/subject.js +++ b/models/subject.js @@ -24,4 +24,3 @@ const subjectcontentSchema = { }; const subjectcontentModel = new connector.model("subjectcontent", subjectcontentSchema); -module.export = {} From 8ca8b446a52504652bfa787d4be9ccb63178dd21 Mon Sep 17 00:00:00 2001 From: Parikshit07 Date: Fri, 16 Jun 2023 15:40:51 +0530 Subject: [PATCH 08/20] crud for group model --- models/group.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 models/group.js diff --git a/models/group.js b/models/group.js new file mode 100644 index 0000000..938fcd4 --- /dev/null +++ b/models/group.js @@ -0,0 +1,55 @@ +const connector = require("#models/databaseUtil"); + +const groupSchema = { + groupName: { type: String, required: true }, + studentIds: { type: [Number], required: true }, +}; + +const groupModel = new connector.model("group", groupSchema); + +async function createGroup(groupData) { + try { + const newGroup = await groupModel.create(groupData); + return newGroup; + } catch (error) { + console.error("Error creating group:", error); + return null; + } +} + +async function getGroupById(groupId) { + try { + const group = await groupModel.findById(groupId); + return group; + } catch (error) { + console.error("Error retrieving group:", error); + return null; + } +} + +async function updateGroup(groupId, updateData) { + try { + const updatedGroup = await groupModel.findByIdAndUpdate(groupId, updateData, { new: true }); + return updatedGroup; + } catch (error) { + console.error("Error updating group:", error); + return null; + } +} + +async function deleteGroup(groupId) { + try { + const deletedGroup = await groupModel.findByIdAndDelete(groupId); + return deletedGroup; + } catch (error) { + console.error("Error deleting group:", error); + return null; + } +} + +module.exports = { + createGroup, + getGroupById, + updateGroup, + deleteGroup, +}; \ No newline at end of file From 0dc8569ae1c7b441bc268bb3ff31a9a9fde88d56 Mon Sep 17 00:00:00 2001 From: Parikshit07 Date: Fri, 16 Jun 2023 16:00:29 +0530 Subject: [PATCH 09/20] replacedd require with import --- models/group.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/models/group.js b/models/group.js index 938fcd4..406005c 100644 --- a/models/group.js +++ b/models/group.js @@ -1,5 +1,4 @@ -const connector = require("#models/databaseUtil"); - +import connector from "#models/databaseUtil"; const groupSchema = { groupName: { type: String, required: true }, studentIds: { type: [Number], required: true }, From 6fd9ddf767983269bedec41a61596d61a5d77591 Mon Sep 17 00:00:00 2001 From: Vinit Date: Mon, 19 Jun 2023 13:51:48 +0530 Subject: [PATCH 10/20] Added PR Template --- ,github/pull_request_template.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ,github/pull_request_template.md diff --git a/,github/pull_request_template.md b/,github/pull_request_template.md new file mode 100644 index 0000000..a62e3e5 --- /dev/null +++ b/,github/pull_request_template.md @@ -0,0 +1,17 @@ +## Description +Briefly describe the changes made in this pull request. + +## Fixes +Specify the related issues or tickets that this pull request fixes (e.g., Fixes #123). + +## Checklist + +- [ ] Code follows project's style guidelines. +- [ ] Changes are documented appropriately. + +## Notes +Add any additional notes or context that might be useful for reviewers. + + + +#### (PS → Make Sure Pull request title is meaningful.) \ No newline at end of file From b01b0b2d563a1db29f4cc51c133d20475776672c Mon Sep 17 00:00:00 2001 From: Shivam Tiwari Date: Tue, 20 Jun 2023 23:50:31 +0530 Subject: [PATCH 11/20] created an schema for the otp store and made the required changes to store the otp into the db --- controller/auth.js | 30 ++++++++++++++++-------------- models/otpStore.js | 10 ++++++++++ 2 files changed, 26 insertions(+), 14 deletions(-) create mode 100644 models/otpStore.js diff --git a/controller/auth.js b/controller/auth.js index a5281a2..fe16a5e 100644 --- a/controller/auth.js +++ b/controller/auth.js @@ -1,8 +1,7 @@ +import OTPStore from "/models/OTPStore"; import util, {logger} from "#util"; import { authenticateUser, userExists, updatePassword } from "#services/user"; -const otpStore = {}; - async function login(req, res) { const { id, password } = req.body; try { @@ -36,7 +35,7 @@ async function sendOTP(req, res) { const { uid, emailId } = req.body; if (await userExists(uid, emailId)) { const otp = Math.floor(1000 + Math.random() * 9000); - otpStore[uid] = otp; + await OTPStore.findOneAndUpdate({ uid }, { otp: otp }, { upsert: true }); util.sendOTP(emailId, otp); res.json({ res: "otp sent to emailID" }); } else { @@ -46,20 +45,23 @@ async function sendOTP(req, res) { async function resetPassword(req, res) { const { uid, otp, password } = req.body; - if (otpStore[uid] === otp) { - try { - await updatePassword(uid, password); - res.json({ res: "successfully updated password" }); - } catch (error) { - logger.log("Error while updating", error) - res.status(500); - if (error.name === "UpdateError") res.json({ err: "Something went wrong while updating password" }); - else res.json({ err: "something went wrong" }); + try{ + const otpData=await OTPStore.find({uid}); + if(otpData.otp ===otp ){ + await updatePassword(uid,password) + res.json({res:"successfully updated password"}) } - } else { - res.json({ err: "incorrect otp" }); + else { + res.json({ err: "Incorrect OTP" }); + } + + } + catch(error){ + console.log(error) + res.json({res:"Something is wrong"}) } } + export default { validateUser, sendOTP, resetPassword, login, diff --git a/models/otpStore.js b/models/otpStore.js new file mode 100644 index 0000000..1486aaa --- /dev/null +++ b/models/otpStore.js @@ -0,0 +1,10 @@ +import connector from "#models/databaseUtil"; +const {Schema}=connector; + +const otpStoreSchema=new Schema({ + otpID:{type:String,unique:true,required:true}, + otp:{type:String,required:true,unique:true} +}) + +const OTPStore=connector.model("OTPStore",otpStoreSchema) + From 88da4526785e6780330500c408439efb7616c78f Mon Sep 17 00:00:00 2001 From: Shivam Tiwari Date: Tue, 20 Jun 2023 23:57:33 +0530 Subject: [PATCH 12/20] made Otpid to uid in otpschema --- models/otpStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/otpStore.js b/models/otpStore.js index 1486aaa..a03adbd 100644 --- a/models/otpStore.js +++ b/models/otpStore.js @@ -2,7 +2,7 @@ import connector from "#models/databaseUtil"; const {Schema}=connector; const otpStoreSchema=new Schema({ - otpID:{type:String,unique:true,required:true}, + uid:{type:String,unique:true,required:true}, otp:{type:String,required:true,unique:true} }) From c2a1454a62303a76c6f429c8cc6655c7c8414e9e Mon Sep 17 00:00:00 2001 From: Vinit Date: Wed, 21 Jun 2023 10:49:57 +0530 Subject: [PATCH 13/20] Updated Changes and resolved the issue --- {,github => .github}/pull_request_template.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {,github => .github}/pull_request_template.md (100%) diff --git a/,github/pull_request_template.md b/.github/pull_request_template.md similarity index 100% rename from ,github/pull_request_template.md rename to .github/pull_request_template.md From 8b3f984a28513711e9a5a197b1ec7ab85d10473e Mon Sep 17 00:00:00 2001 From: Vinit Date: Wed, 21 Jun 2023 11:05:05 +0530 Subject: [PATCH 14/20] Issues fixes#93 --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a62e3e5..6d8c40f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -5,7 +5,7 @@ Briefly describe the changes made in this pull request. Specify the related issues or tickets that this pull request fixes (e.g., Fixes #123). ## Checklist - + - [ ] Code follows project's style guidelines. - [ ] Changes are documented appropriately. From e2c50ef0823d7170cc3767f901c602568245641d Mon Sep 17 00:00:00 2001 From: tanmay Date: Sat, 24 Jun 2023 19:30:11 +0530 Subject: [PATCH 15/20] add organization model --- models/organization.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 models/organization.js diff --git a/models/organization.js b/models/organization.js new file mode 100644 index 0000000..d70cfa8 --- /dev/null +++ b/models/organization.js @@ -0,0 +1,14 @@ +import connector from "./databaseUtil"; + +const organizationSchema = { + parent: { type: connector.Schema.Types.ObjectId, ref: "Organization", required: "true" }, + orgID: { type: String, required: true }, + orgName: { type: String, required: true }, + orgAddress: { type: String, required: true }, + orgInfra: [{ type: connector.Schema.Types.ObjectId, ref: "Infrastructure", required: "true" }], + accreditation: { type: connector.Schema.Types.ObjectId, ref: "Accrediation", required: "true" }, + department: [{ type: connector.Schema.Types.ObjectId, ref: "Department", required: "true" }], + employees: [{ type: connector.Schema.Types.ObjectId, ref: "Faculty", required: "true" }], + +}; +const Organization = new connector.model("Organization", organizationSchema); From 78604ad22a83517572d1d724368e2e735738b5fb Mon Sep 17 00:00:00 2001 From: Hitansh Doshi Date: Tue, 27 Jun 2023 22:43:20 +0530 Subject: [PATCH 16/20] added logger import back in models/user.js --- models/user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/models/user.js b/models/user.js index ca13c10..eb051db 100644 --- a/models/user.js +++ b/models/user.js @@ -1,4 +1,5 @@ import connector from "#models/databaseUtil"; +import { logger } from "#util"; connector.set("debug", true); const userSchema = { From 112bdf7edfb39e60652b08c2d41c347fc943a942 Mon Sep 17 00:00:00 2001 From: Hitansh Doshi Date: Wed, 28 Jun 2023 00:01:42 +0530 Subject: [PATCH 17/20] refactored and restructured the code --- controller/auth.js | 29 ++++++++++++++--------------- models/otpStore.js | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/controller/auth.js b/controller/auth.js index fe16a5e..d38860f 100644 --- a/controller/auth.js +++ b/controller/auth.js @@ -1,4 +1,4 @@ -import OTPStore from "/models/OTPStore"; +import OTPStore from "#models/otpStore"; import util, {logger} from "#util"; import { authenticateUser, userExists, updatePassword } from "#services/user"; @@ -35,7 +35,7 @@ async function sendOTP(req, res) { const { uid, emailId } = req.body; if (await userExists(uid, emailId)) { const otp = Math.floor(1000 + Math.random() * 9000); - await OTPStore.findOneAndUpdate({ uid }, { otp: otp }, { upsert: true }); + await OTPStore.update({uid: uid}, {otp: otp}); util.sendOTP(emailId, otp); res.json({ res: "otp sent to emailID" }); } else { @@ -45,20 +45,19 @@ async function sendOTP(req, res) { async function resetPassword(req, res) { const { uid, otp, password } = req.body; - try{ - const otpData=await OTPStore.find({uid}); - if(otpData.otp ===otp ){ - await updatePassword(uid,password) - res.json({res:"successfully updated password"}) - } - else { - res.json({ err: "Incorrect OTP" }); + const storedOtp = await OTPStore.read({uid: uid}); + if (storedOtp[0].otp === `${otp}`) { + try { + await updatePassword(uid, password); + res.json({ res: "successfully updated password" }); + } catch (error) { + logger.log("Error while updating", error) + res.status(500); + if (error.name === "UpdateError") res.json({ err: "Something went wrong while updating password" }); + else res.json({ err: "something went wrong" }); } - - } - catch(error){ - console.log(error) - res.json({res:"Something is wrong"}) + } else { + res.json({ err: "incorrect otp" }); } } diff --git a/models/otpStore.js b/models/otpStore.js index a03adbd..45648b8 100644 --- a/models/otpStore.js +++ b/models/otpStore.js @@ -1,10 +1,38 @@ import connector from "#models/databaseUtil"; -const {Schema}=connector; -const otpStoreSchema=new Schema({ - uid:{type:String,unique:true,required:true}, - otp:{type:String,required:true,unique:true} -}) +const otpStoreSchema = { + uid: { type: String, unique: true, required: true }, + otp: { type: String, unique: true, required: true } +} -const OTPStore=connector.model("OTPStore",otpStoreSchema) +const OTPStore = connector.model("OTPStore", otpStoreSchema) + +async function remove(filter) { + const res = await OTPStore.findOneAndDelete(filter); + return res; +} + +async function create(uid, otp) { + const otpStore = new OTPStore({ + uid, + otp + }); + const otpDoc = await otpStore.save(); + return otpDoc; +} + +async function read(filter, limit = 1) { + const otpData = await OTPStore.find(filter).limit(limit); + return otpData; +} + +async function update(filter, updateObject) { + const otpDoc = await OTPStore.findOneAndUpdate(filter, updateObject, { upsert: true, new: true }); + return otpDoc; +} + + +export default { + create, read, update, remove, +}; From be052ecf156ffbd530ab88da30211f394867b9e7 Mon Sep 17 00:00:00 2001 From: Hitansh Doshi Date: Wed, 28 Jun 2023 00:45:15 +0530 Subject: [PATCH 18/20] fixed syntax according to eslint --- controller/auth.js | 11 +++--- controller/user.js | 4 +-- middleware/auth.js | 12 ++++--- models/accreditation.js | 2 +- models/attendance.js | 10 +++--- models/faculty.js | 14 ++++---- models/group.js | 73 +++++++++++++++++++-------------------- models/infra.js | 2 +- models/module.js | 6 ++-- models/organization.js | 4 ++- models/otpStore.js | 10 +++--- models/subject.js | 44 ++++++++++++------------ models/user.js | 6 ++-- services/user.js | 4 +-- util.js | 75 ++++++++++++++++++++++------------------- 15 files changed, 144 insertions(+), 133 deletions(-) diff --git a/controller/auth.js b/controller/auth.js index d38860f..3db5753 100644 --- a/controller/auth.js +++ b/controller/auth.js @@ -1,5 +1,5 @@ import OTPStore from "#models/otpStore"; -import util, {logger} from "#util"; +import util, { logger } from "#util"; import { authenticateUser, userExists, updatePassword } from "#services/user"; async function login(req, res) { @@ -16,7 +16,7 @@ async function login(req, res) { userDetails.token = token; res.json({ res: "welcome", user: userDetails }); } catch (error) { - logger.error("Error while login", error) + logger.error("Error while login", error); if (error.name === "UserDoesNotExist") { res.status(403); res.json({ err: "Incorrect ID password" }); @@ -35,7 +35,7 @@ async function sendOTP(req, res) { const { uid, emailId } = req.body; if (await userExists(uid, emailId)) { const otp = Math.floor(1000 + Math.random() * 9000); - await OTPStore.update({uid: uid}, {otp: otp}); + await OTPStore.update({ uid }, { otp }); util.sendOTP(emailId, otp); res.json({ res: "otp sent to emailID" }); } else { @@ -45,13 +45,13 @@ async function sendOTP(req, res) { async function resetPassword(req, res) { const { uid, otp, password } = req.body; - const storedOtp = await OTPStore.read({uid: uid}); + const storedOtp = await OTPStore.read({ uid }); if (storedOtp[0].otp === `${otp}`) { try { await updatePassword(uid, password); res.json({ res: "successfully updated password" }); } catch (error) { - logger.log("Error while updating", error) + logger.log("Error while updating", error); res.status(500); if (error.name === "UpdateError") res.json({ err: "Something went wrong while updating password" }); else res.json({ err: "something went wrong" }); @@ -60,7 +60,6 @@ async function resetPassword(req, res) { res.json({ err: "incorrect otp" }); } } - export default { validateUser, sendOTP, resetPassword, login, diff --git a/controller/user.js b/controller/user.js index a3e94ac..20efc5c 100644 --- a/controller/user.js +++ b/controller/user.js @@ -9,8 +9,8 @@ async function addUser(req, res) { const newUser = await createUser(name, password, emailId, uid, userType); res.json({ res: `added user ${newUser.id}` }); } catch (error) { - logger.error("Error while inserting", error) - res.status(500) + logger.error("Error while inserting", error); + res.status(500); res.json({ err: "Error while inserting in DB" }); } } diff --git a/middleware/auth.js b/middleware/auth.js index 74418f0..016483d 100644 --- a/middleware/auth.js +++ b/middleware/auth.js @@ -1,5 +1,5 @@ import jwt from "jsonwebtoken"; -import util, {logger} from "#util"; +import util from "#util"; async function authenticateToken(req, res, next) { const authHeader = req.headers.authorization; @@ -9,15 +9,17 @@ async function authenticateToken(req, res, next) { const payload = jwt.verify(token, process.env.TOKEN_SECRET); const decryptedIP = util.decrypt(payload.ip); if (decryptedIP !== req.ip) { - res.status(403) - res.send({err:"Unauthorized"}); + res.status(403); + res.send({ err: "Unauthorized" }); } req.user = payload.data; next(); + return true; } catch (error) { - res.status(403) - res.send({err:"Unauthorized"}); + res.status(403); + res.send({ err: "Unauthorized" }); + return false; } } diff --git a/models/accreditation.js b/models/accreditation.js index cd75537..7d62077 100644 --- a/models/accreditation.js +++ b/models/accreditation.js @@ -8,7 +8,7 @@ const accreditationSchema = { dateofExpiry: { type: Date, required: true }, }; -const Accreditation = new connector.model("Accreditation", accreditationSchema); +const Accreditation = connector.model("Accreditation", accreditationSchema); async function remove(filter) { const res = await Accreditation.findOneAndDelete(filter); diff --git a/models/attendance.js b/models/attendance.js index d5ced3c..5b0a723 100644 --- a/models/attendance.js +++ b/models/attendance.js @@ -1,5 +1,4 @@ import connector from "./databaseUtil"; -import Infrastructure from "./infrastructure"; connector.set("debug", true); @@ -7,7 +6,6 @@ const attendanceSchema = { date: { type: Date, required: true }, time: { type: String, required: true }, absentees: { type: Array }, - class: Infrastructure, }; const Attendance = connector.model("Attendance", attendanceSchema); @@ -28,10 +26,14 @@ async function remove(filter) { } async function grantAttendance(roll, date) { - const res = await Attendance.findOneAndUpdate(date, {$pull: { absentees: roll } }, { new: true }); + const res = await Attendance.findOneAndUpdate( + date, + { $pull: { absentees: roll } }, + { new: true }, + ); return res; } export default { create, remove, grantAttendance, -}; \ No newline at end of file +}; diff --git a/models/faculty.js b/models/faculty.js index 3e74312..54e6f72 100644 --- a/models/faculty.js +++ b/models/faculty.js @@ -1,13 +1,13 @@ -const { connector } = require('./databaseUtil'); +const { connector } = require("./databaseUtil"); -const facultySchema = new mongoose.Schema({ +const facultySchema = { name: { type: String, required: true, }, department: { - type: mongoose.Schema.Types.ObjectId, - ref: 'Department', + type: connector.Schema.Types.ObjectId, + ref: "Department", required: true, }, empType: { @@ -19,7 +19,7 @@ const facultySchema = new mongoose.Schema({ required: true, }, preferredSubjects: { - type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Subject' }], + type: [{ type: connector.Schema.Types.ObjectId, ref: "Subject" }], required: true, }, profileLink: { @@ -87,8 +87,8 @@ const facultySchema = new mongoose.Schema({ type: Date, default: Date.now, }, -}); +}; -const Faculty = connector.model('Faculty', facultySchema); +const Faculty = connector.model("Faculty", facultySchema); module.exports = Faculty; diff --git a/models/group.js b/models/group.js index d5c7bbd..19118eb 100644 --- a/models/group.js +++ b/models/group.js @@ -1,54 +1,55 @@ import connector from "#models/databaseUtil"; + const groupSchema = { - groupName: { type: String, required: true }, - studentIds: { type: [Number], required: true }, + groupName: { type: String, required: true }, + studentIds: { type: [Number], required: true }, }; -const groupModel = new connector.model("group", groupSchema); +const groupModel = connector.model("group", groupSchema); async function createGroup(groupData) { - try { - const newGroup = await groupModel.create(groupData); - return newGroup; - } catch (error) { - console.error("Error creating group:", error); - return null; - } + try { + const newGroup = await groupModel.create(groupData); + return newGroup; + } catch (error) { + console.error("Error creating group:", error); + return null; + } } async function getGroupById(groupId) { - try { - const group = await groupModel.findById(groupId); - return group; - } catch (error) { - console.error("Error retrieving group:", error); - return null; - } + try { + const group = await groupModel.findById(groupId); + return group; + } catch (error) { + console.error("Error retrieving group:", error); + return null; + } } async function updateGroup(groupId, updateData) { - try { - const updatedGroup = await groupModel.findByIdAndUpdate(groupId, updateData, { new: true }); - return updatedGroup; - } catch (error) { - console.error("Error updating group:", error); - return null; - } + try { + const updatedGroup = await groupModel.findByIdAndUpdate(groupId, updateData, { new: true }); + return updatedGroup; + } catch (error) { + console.error("Error updating group:", error); + return null; + } } async function deleteGroup(groupId) { - try { - const deletedGroup = await groupModel.findByIdAndDelete(groupId); - return deletedGroup; - } catch (error) { - console.error("Error deleting group:", error); - return null; - } + try { + const deletedGroup = await groupModel.findByIdAndDelete(groupId); + return deletedGroup; + } catch (error) { + console.error("Error deleting group:", error); + return null; + } } -module.exports = { - createGroup, - getGroupById, - updateGroup, - deleteGroup, +export default { + createGroup, + getGroupById, + updateGroup, + deleteGroup, }; diff --git a/models/infra.js b/models/infra.js index ec2bac8..37c5c16 100644 --- a/models/infra.js +++ b/models/infra.js @@ -8,7 +8,7 @@ const infrastructureSchema = { capacity: { type: Number, required: true }, }; -const Infrastructure = new connector.model("Infrastructure", infrastructureSchema); +const Infrastructure = connector.model("Infrastructure", infrastructureSchema); async function remove(filter) { const res = await Infrastructure.findOneAndDelete(filter); diff --git a/models/module.js b/models/module.js index 3387f38..3ce94ee 100644 --- a/models/module.js +++ b/models/module.js @@ -1,4 +1,4 @@ -import connector from '#models/databaseUtil'; +import connector from "#models/databaseUtil"; const moduleSchema = { moduleNo: { type: Number, required: true }, @@ -9,7 +9,7 @@ const moduleSchema = { cognitiveLevels: [{ type: String, required: true }], }; -const Module = new connector.model('Module', moduleSchema); +const Module = connector.model("Module", moduleSchema); async function remove(filter) { const res = await Module.findOneAndDelete(filter); @@ -22,7 +22,7 @@ async function create( moduleOutcome, moduleContents, hrsPerModule, - cognitiveLevels + cognitiveLevels, ) { const module = new Module({ moduleNo, diff --git a/models/organization.js b/models/organization.js index d70cfa8..95ba478 100644 --- a/models/organization.js +++ b/models/organization.js @@ -11,4 +11,6 @@ const organizationSchema = { employees: [{ type: connector.Schema.Types.ObjectId, ref: "Faculty", required: "true" }], }; -const Organization = new connector.model("Organization", organizationSchema); + +// eslint-disable-next-line no-unused-vars +const Organization = connector.model("Organization", organizationSchema); diff --git a/models/otpStore.js b/models/otpStore.js index 45648b8..6695e49 100644 --- a/models/otpStore.js +++ b/models/otpStore.js @@ -2,10 +2,10 @@ import connector from "#models/databaseUtil"; const otpStoreSchema = { uid: { type: String, unique: true, required: true }, - otp: { type: String, unique: true, required: true } -} + otp: { type: String, unique: true, required: true }, +}; -const OTPStore = connector.model("OTPStore", otpStoreSchema) +const OTPStore = connector.model("OTPStore", otpStoreSchema); async function remove(filter) { const res = await OTPStore.findOneAndDelete(filter); @@ -15,7 +15,7 @@ async function remove(filter) { async function create(uid, otp) { const otpStore = new OTPStore({ uid, - otp + otp, }); const otpDoc = await otpStore.save(); return otpDoc; @@ -31,8 +31,6 @@ async function update(filter, updateObject) { return otpDoc; } - export default { create, read, update, remove, }; - diff --git a/models/subject.js b/models/subject.js index 31b5fbf..e014bcc 100644 --- a/models/subject.js +++ b/models/subject.js @@ -1,26 +1,26 @@ const { connector } = require("#models/databaseUtil"); -const { Module } = require("#models/module"); -const { Practical} = require("#models/practical"); const subjectcontentSchema = { - courseCode: {type: String, required: true}, - courseName: {type: String, required: true}, - totalCredit: {type: Number, required: true}, - duration: {type: Number, required: true}, - subID: {type: String, required: true}, - subName: {type:String, required: true}, - semester: {type: String, required: true}, - ltpCredDist: {type: [Number], required: true}, - subType: {type: String, enum: ["open", "professional", "core"], required: true}, // can be open, professional, or core - prerequisites: {type: String, required: true}, - courseObjective:{type: String, required: true}, - courseOutcomes : [{courseOutcome:{type: String}, RBTLevel: {type:String}}], //this is the modules from syllabus - modules: {type: [Module], required: true}, - reccTextbooks: {type: [String], required: true}, - refBooks: {type: [String], required: true}, - evalScheme: {type: [Number], required: true}, - maxMarks: {type: Number, required: true}, - practicals: {type: [Practical], required: true} -}; + courseCode: { type: String, required: true }, + courseName: { type: String, required: true }, + totalCredit: { type: Number, required: true }, + duration: { type: Number, required: true }, + subID: { type: String, required: true }, + subName: { type: String, required: true }, + semester: { type: String, required: true }, + ltpCredDist: { type: [Number], required: true }, + subType: { type: String, enum: ["open", "professional", "core"], required: true }, // can be open, professional, or core + prerequisites: { type: String, required: true }, + courseObjective: { type: String, required: true }, + courseOutcomes: [{ + courseOutcome: { type: String }, + RBTLevel: { type: String }, + }], // this is the modules from syllabus + reccTextbooks: { type: [String], required: true }, + refBooks: { type: [String], required: true }, + evalScheme: { type: [Number], required: true }, + maxMarks: { type: Number, required: true }, +}; -const subjectcontentModel = new connector.model("subjectcontent", subjectcontentSchema); +// eslint-disable-next-line no-unused-vars +const subjectcontentModel = connector.model("subjectcontent", subjectcontentSchema); diff --git a/models/user.js b/models/user.js index b2bb635..17e63cd 100644 --- a/models/user.js +++ b/models/user.js @@ -1,5 +1,5 @@ import connector from "#models/databaseUtil"; -import { hashPassword, logger } from "#util"; +import { hashPassword } from "#util"; connector.set("debug", true); const userSchema = { @@ -17,8 +17,8 @@ async function remove(filter) { return res; } -async function create(name, password, emailId, uid, userType) { - password = await hashPassword(password); +async function create(name, pass, emailId, uid, userType) { + const password = await hashPassword(pass); const user = new User({ name, password, diff --git a/services/user.js b/services/user.js index e2e8265..b45fe34 100644 --- a/services/user.js +++ b/services/user.js @@ -1,10 +1,10 @@ import User from "#models/user"; import databaseError from "#error/database"; -import { comparePasswords, hashPassword, logger } from "#util"; +import { comparePasswords, hashPassword } from "#util"; export async function authenticateUser(uid, password) { const user = await User.read({ uid }, 1); - const passwordMatched = await comparePasswords(password, user[0]?.password); + const passwordMatched = await comparePasswords(password, user[0]?.password); if (passwordMatched) { return user[0]; } diff --git a/util.js b/util.js index b029159..e7ff739 100644 --- a/util.js +++ b/util.js @@ -1,7 +1,7 @@ import jwt from "jsonwebtoken"; import nodemailer from "nodemailer"; import { logLevel } from "#constant"; -import crypto from "crypto" +import crypto from "crypto"; import "winston-daily-rotate-file"; import winston from "winston"; import dotenv from "dotenv"; @@ -24,26 +24,26 @@ const transporter = nodemailer.createTransport({ const key = crypto.randomBytes(32); const iv = crypto.randomBytes(16); -const algorithm = 'aes-256-cbc'; +const algorithm = "aes-256-cbc"; const encrypt = (IP) => { - const cipher = crypto.createCipheriv(algorithm, key, iv); - let encrypted = cipher.update(IP, 'utf8', 'hex'); - encrypted += cipher.final('hex'); - return encrypted; -} + const cipher = crypto.createCipheriv(algorithm, key, iv); + let encrypted = cipher.update(IP, "utf8", "hex"); + encrypted += cipher.final("hex"); + return encrypted; +}; const decrypt = (IP) => { - const decipher = crypto.createDecipheriv(algorithm, key, iv); - let decrypted = decipher.update(IP, 'hex', 'utf8'); - decrypted += decipher.final('utf8'); - return decrypted; -} + const decipher = crypto.createDecipheriv(algorithm, key, iv); + let decrypted = decipher.update(IP, "hex", "utf8"); + decrypted += decipher.final("utf8"); + return decrypted; +}; -const generateToken = (data, IP)=>{ +const generateToken = (data, IP) => { const encryptedIP = encrypt(IP); - return jwt.sign({data: data, ip: encryptedIP}, process.env.TOKEN_SECRET); -} + return jwt.sign({ data, ip: encryptedIP }, process.env.TOKEN_SECRET); +}; const sendOTP = async (to, otp) => { await transporter.sendMail({ @@ -54,24 +54,24 @@ const sendOTP = async (to, otp) => { }); }; -export const hashPassword = async(password) =>{ - try { - const salt = await bcrypt.genSalt(10); - const hashedPassword = await bcrypt.hash(password,salt); - return hashedPassword; - } catch (error) { - return error.message; - } -} - -export const comparePasswords = async(userPassword,storedPassword) =>{ - try { - const matched = await bcrypt.compare(userPassword,storedPassword); - return matched - } catch (error) { - return error.message; - } -} +export const hashPassword = async (password) => { + try { + const salt = await bcrypt.genSalt(10); + const hashedPassword = await bcrypt.hash(password, salt); + return hashedPassword; + } catch (error) { + return error.message; + } +}; + +export const comparePasswords = async (userPassword, storedPassword) => { + try { + const matched = await bcrypt.compare(userPassword, storedPassword); + return matched; + } catch (error) { + return error.message; + } +}; /** * @@ -143,5 +143,12 @@ logger.stream = { }; export default { - generateToken, encrypt, decrypt, sendOTP, asyncPlaceholders, logger, hashPassword, comparePasswords, + generateToken, + encrypt, + decrypt, + sendOTP, + asyncPlaceholders, + logger, + hashPassword, + comparePasswords, }; From 548d127bfdbe27a97de4bc5b46d7f68b29d16af1 Mon Sep 17 00:00:00 2001 From: Hitansh Doshi Date: Wed, 28 Jun 2023 01:08:03 +0530 Subject: [PATCH 19/20] added eslint script and git precommit hook --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a1c5aea..1f1d7d1 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "serverstartWin": "SET DEBUG=api:* && npm run devstart", "test": "NODE_OPTIONS=--experimental-vm-modules npx jest", "test:watch": "NODE_OPTIONS=--experimental-vm-modules npx jest --watch", - "test:openHandels": "NODE_OPTIONS=--experimental-vm-modules npx jest --detectOpenHandles" + "test:openHandels": "NODE_OPTIONS=--experimental-vm-modules npx jest --detectOpenHandles", + "eslint": "eslint '**/*.js'" }, "dependencies": { "bcrypt": "^5.1.0", From ee83a2ea06ffc991dc6799a008b76e33bd5200b0 Mon Sep 17 00:00:00 2001 From: Vinit Date: Thu, 29 Jun 2023 16:10:52 +0530 Subject: [PATCH 20/20] Removed UID from the file --- models/accreditation.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/models/accreditation.js b/models/accreditation.js index cd75537..6af0878 100644 --- a/models/accreditation.js +++ b/models/accreditation.js @@ -1,7 +1,6 @@ import connector from "#models/databaseUtil"; const accreditationSchema = { - uid: { type: String, unique: true, required: true }, accreditationName: { type: String, required: true }, agencyName: { type: String, required: true }, dateofAccreditation: { type: Date, required: true }, @@ -15,11 +14,10 @@ async function remove(filter) { return res; } -async function create(uid, accreditationName, agencyName, dateofAccreditation, dateofExpiry) { +async function create(accreditationName, agencyName, dateofAccreditation, dateofExpiry) { const accreditation = new Accreditation({ accreditationName, agencyName, - uid, dateofAccreditation, dateofExpiry, });