diff --git a/app.js b/app.js index 49c4f40..8978b68 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,4 @@ -require('./config/mongoose') +const Connection = require('./config/mongoose') const express = require('express') const morgan = require('morgan') const cookieParser = require('cookie-parser') @@ -22,92 +22,131 @@ const commentRouter = require('./app/routes/comment') const projectRouter = require('./app/routes/project') const notificationRouter = require('./app/routes/notification') const proposalRouter = require('./app/routes/proposal') - const app = express() const server = require('http').Server(app) - -app.use(cors()) - -app.use(bodyParser.json({ limit: '200mb' })) -app.use(bodyParser.urlencoded(fileConstants.fileParameters)) - -const memoryStorage = multer.memoryStorage() -app.use(multer({ storage: memoryStorage }).single('file')) - if (process.env.NODE_ENV !== 'testing') { server.listen(process.env.SOCKET_PORT || 8810) } // WARNING: app.listen(80) will NOT work here! - const io = socket.listen(server) -let count = 0 -io.on('connection', (socket) => { - console.log('socket connected count ', count++) - io.emit('user connected') -}) - -// view engine setup -app.set('views', path.join(__dirname, 'views')) -app.set('view engine', 'ejs') - -morgan.token('data', (req, res) => { - return JSON.stringify(req.body) -}) - -app.use( - morgan( - ':remote-addr - :remote-user [:date[clf]] ":method :url" :status :res[content-length] ":referrer" ":user-agent" :data', - { stream: winston.stream } - ) -) - -app.use(express.json()) -app.use(express.urlencoded({ extended: false })) -app.use(cookieParser()) -app.use(express.static(path.join(__dirname, 'public'))) -app.use((req, res, next) => { - req.io = io - next() -}) - -app.use('/notification', notificationRouter) -app.use('/', indexRouter) -app.use('/auth', authRouter) -app.use('/user', usersRouter) -app.use('/post', postRouter) -app.use('/org', organizationRouter) -app.use('/event', eventRouter) -app.use('/shortUrl', shortUrlRouter) -app.use('/comment', commentRouter) -app.use('/project', projectRouter) -app.use('/proposal', proposalRouter) - -// catch 404 and forward to error handler -app.use(function (req, res, next) { - next(createError(404, "route doesn't exist")) -}) - -// error handler -app.use(function (err, req, res, next) { - // set locals, only providing error in development - res.locals.message = err.message - res.locals.error = req.app.get('env') === 'development' ? err : {} - - // To include winston logging (Error) - winston.error( - `${err.status || 500} - ${err.message} - ${req.originalUrl} - ${req.method} - ${req.ip} - ${req.body}` - ) - - // render the error page - res.status(err.status || 500) - res.render('error') - - // Socket event error handler (On max event) - req.io.on('error', function (err) { - console.error('------REQ ERROR') - console.error(err.stack) - }) - next() -}) +class ServerBuilder { + constructor () { + this.#initDB() + this.#initMiddleware() + this.#initViewEngine() + this.#initLogger() + this.#initSocket() + this.#initRouter() + this.#initErrorHandler() + } + + // PRIVATE METHOD (ES6) + #initDB = async () => { + await Connection.connect() + } + + // PRIVATE METHOD (ES6) + #initMiddleware = () => { + app.use(cors()) + + app.use(bodyParser.json({ limit: '200mb' })) + app.use(bodyParser.urlencoded(fileConstants.fileParameters)) + + const memoryStorage = multer.memoryStorage() + app.use(multer({ storage: memoryStorage }).single('file')) + app.use(express.json()) + app.use(express.urlencoded({ + extended: false + })) + app.use(cookieParser()) + } + + // PRIVATE METHOD (ES6) + #initViewEngine = () => { + // view engine setup + app.set('views', path.join(__dirname, 'views')) + app.set('view engine', 'ejs') + } + + // PRIVATE METHOD (ES6) + #initLogger = () => { + morgan.token('data', (req, res) => { + return JSON.stringify(req.body) + }) + app.use( + morgan( + ':remote-addr - :remote-user [:date[clf]] ":method :url" :status :res[content-length] ":referrer" ":user-agent" :data', { + stream: winston.stream + } + ) + ) + } + + // PRIVATE METHOD (ES6) + #initSocket = () => { + let count = 0 + io.on('connection', (socket) => { + console.log('socket connected count ', count++) + io.emit('user connected') + }) + app.use(express.static(path.join(__dirname, 'public'))) + app.use((req, res, next) => { + req.io = io + next() + }) + } + + // PRIVATE METHOD (ES6) + #initRouter = () => { + app.use('/notification', notificationRouter) + app.use('/', indexRouter) + app.use('/auth', authRouter) + app.use('/user', usersRouter) + app.use('/post', postRouter) + app.use('/org', organizationRouter) + app.use('/event', eventRouter) + app.use('/shortUrl', shortUrlRouter) + app.use('/comment', commentRouter) + app.use('/project', projectRouter) + app.use('/proposal', proposalRouter) + } + + // PRIVATE METHOD (ES6) + #initErrorHandler = () => { + // catch 404 and forward to error handler + app.use(function (req, res, next) { + next(createError(404, "route doesn't exist")) + }) + + // error handler + app.use(function (err, req, res, next) { + // set locals, only providing error in development + res.locals.message = err.message + res.locals.error = req.app.get('env') === 'development' ? err : {} + + // To include winston logging (Error) + winston.error( + `${err.status || 500} - ${err.message} - ${req.originalUrl} - ${req.method} - ${req.ip} - ${req.body}` + ) + + // render the error page + res.status(err.status || 500) + res.render('error') + + // Socket event error handler (On max event) + req.io.on('error', function (err) { + console.error('------REQ ERROR') + console.error(err.stack) + }) + next() + }) + } + static startServer() { + return new ServerBuilder() + } +} + +// STATIC METHOD CALLED +ServerBuilder.startServer() module.exports = { app, io } diff --git a/app/controllers/auth.js b/app/controllers/auth.js index 20f101f..0013891 100644 --- a/app/controllers/auth.js +++ b/app/controllers/auth.js @@ -1,21 +1,36 @@ -const User = require('../models/User') const HttpStatus = require('http-status-codes') -module.exports = { - authenticateUser: async (req, res, next) => { + +class Auth { + constructor (UserModel) { + this.UserModel = UserModel + this.#initBinding() + } + + // PRIVATE ES6 + #initBinding = () => { + this.authenticateUser = this.authenticateUser.bind(this) + this.logout = this.logout.bind(this) + this.logoutAll = this.logoutAll.bind(this) + } + + async authenticateUser (req, res, next) { const email = req.body.email const password = req.body.password try { - const user = await User.findByCredentials(email, password) + const user = await this.UserModel.findByCredentials(email, password) const token = await user.generateAuthToken() res.send({ user: user, token: token }) } catch (error) { res.status(HttpStatus.BAD_REQUEST).json({ error: error.message }) } - }, - logout: (req, res, next) => { + } + + logout (req, res, next) { res.status(HttpStatus.OK).json({ success: 'ok' }) - }, - logoutAll: (req, res, next) => { + } + + logoutAll (req, res, next) { res.status(HttpStatus.OK).json({ success: 'ok' }) } } +module.exports = Auth diff --git a/app/controllers/comment.js b/app/controllers/comment.js index 7517731..0571752 100644 --- a/app/controllers/comment.js +++ b/app/controllers/comment.js @@ -1,16 +1,30 @@ const HANDLER = require('../utils/response-helper') const HttpStatus = require('http-status-codes') -const CommentModel = require('../models/Comment') const permission = require('../utils/permission') const helper = require('../utils/paginate') -module.exports = { +class Comment { + constructor(CommentModel) { + this.CommentModel = CommentModel + this.#initBinding() + } + + // PRIVATE ES6 + #initBinding = () => { + this.comment = this.comment.bind(this) + this.update = this.update.bind(this) + this.delete = this.delete.bind(this) + this.getCommentByPost = this.getCommentByPost.bind(this) + this.upvote= this.upvote.bind(this) + this.downvote = this.downvote.bind(this) + } + // CREATE COMMENT (ISSUE IN CREATE COMMENT ) - comment: async (req, res, next) => { + async comment(req, res, next) { const { id } = req.params const userId = req.user.id.toString() try { - const comment = new CommentModel(req.body) + const comment = new this.CommentModel(req.body) comment.userId = userId comment.postId = id // added postId await comment.save() @@ -18,13 +32,13 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // DELETE COMMENT - delete: async (req, res, next) => { + async delete(req, res, next) { const { id } = req.params try { - const comment = await CommentModel.findById(id) + const comment = await this.CommentModel.findById(id) if (!comment) { return res.status(HttpStatus.NOT_FOUND).json({ error: 'No comment exist' }) } @@ -32,15 +46,15 @@ module.exports = { if (!permission.check(req, res, comment.userId)) { return res.status(HttpStatus.FORBIDDEN).json({ message: 'Bad delete request' }) } - await CommentModel.findByIdAndRemove(id) + await this.CommentModel.findByIdAndRemove(id) res.status(HttpStatus.OK).json({ comment: comment }) } catch (error) { HANDLER.handleError(res, error) } - }, + } // UPDATE COMMENT - update: async (req, res, next) => { + async update(req, res, next) { const { id } = req.params const updates = Object.keys(req.body) const valid = ['content'] @@ -51,7 +65,7 @@ module.exports = { return res.status(HttpStatus.BAD_REQUEST).json({ error: 'Wrong Update Request' }) } try { - const comment = await CommentModel.findById(id) + const comment = await this.CommentModel.findById(id) if (!comment) { return res.status(HttpStatus.NOT_FOUND).json({ error: 'No comment exist' }) } @@ -67,13 +81,13 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // GET ALL COMMENTS OF A POST BY postId - getCommentByPost: async (req, res, next) => { + async getCommentByPost(req, res, next) { const { id } = req.params try { - const comments = await CommentModel.find({ postId: id }, {}, helper.paginate(req)) + const comments = await this.CommentModel.find({ postId: id }, {}, helper.paginate(req)) .populate('userId', ['name.firstName', 'name.lastName']) .sort({ updatedAt: -1 }) .lean() @@ -85,14 +99,14 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // UPVOTE COMMENT - upvote: async (req, res, next) => { + async upvote(req, res, next) { const { id } = req.params const userId = req.user.id.toString() try { - const comment = await CommentModel.findById(id) + const comment = await this.CommentModel.findById(id) if (!comment) { return res.status(HttpStatus.NOT_FOUND).json({ error: 'No comment found' }) } @@ -116,14 +130,14 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // DOWNVOTE COMMENT - downvote: async (req, res, next) => { + async downvote(req, res, next) { const { id } = req.params const userId = req.user.id.toString() try { - const comment = await CommentModel.findById(id) + const comment = await this.CommentModel.findById(id) if (!comment) { return res.status(HttpStatus.NOT_FOUND).json({ error: 'No comment found' }) } @@ -149,3 +163,5 @@ module.exports = { } } } + +module.exports = Comment diff --git a/app/controllers/event.js b/app/controllers/event.js index ebc17fa..84f1301 100644 --- a/app/controllers/event.js +++ b/app/controllers/event.js @@ -5,34 +5,55 @@ const permission = require('../utils/permission') const helper = require('../utils/paginate') const notificationHelper = require('../utils/notif-helper') const settingsHelper = require('../utils/settingHelpers') -const notification = { - heading: '', - content: '', - tag: '' -} +const Notification = require('../utils/notificationClass') +const TAGS = require('../utils/notificationTags') + +class EventClass extends Notification { + constructor (eventModel) { + super() + this.#initDB(eventModel) + this.#initBinding() + } + // (PRIVATE) ES6 + #initDB = (eventModel) => { + this.EventModel = eventModel + } -module.exports = { - createEvent: async (req, res, next) => { - const event = new Event(req.body) + // (PRIVATE) ES6 + #initBinding = () => { + this.createEvent = this.createEvent.bind(this) + this.updateEvent = this.updateEvent.bind(this) + this.deleteEvent = this.deleteEvent.bind(this) + this.GetAllEvent = this.GetAllEvent.bind(this) + this.GetEventById = this.GetEventById.bind(this) + this.getAllEventByUser = this.getAllEventByUser.bind(this) + this.rsvp = this.rsvp.bind(this) + this.UpComingEvents = this.UpComingEvents.bind(this) + } + + async createEvent (req, res, next) { + const event = new this.EventModel(req.body) try { event.createdBy = req.user._id await event.save() req.io.emit('new event created', { data: event.eventName }) - notification.heading = 'New Event!' - notification.content = `${event.eventName} is added!` - notification.tag = 'New!' - notificationHelper.addToNotificationForAll(req, res, notification, next) + const newNotif = this.pushNotification( + 'New Event!', + `${event.eventName} is added!`, + TAGS.NEW + ) + notificationHelper.addToNotificationForAll(req, res, newNotif, next) res.status(HttpStatus.CREATED).json({ event: event }) } catch (error) { res.status(HttpStatus.BAD_REQUEST).json({ error: error }) } - }, + } - updateEvent: async (req, res, next) => { + async updateEvent (req, res, next) { const { id } = req.params const updates = Object.keys(req.body) try { - const event = await Event.findById(id) + const event = await this.EventModel.findById(id) if (!event) { return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'No post exists' }) } @@ -49,22 +70,23 @@ module.exports = { }) await event.save() req.io.emit('event update', { data: `Event: ${event.eventName} is updated!` }) - notification.heading = 'Event update!' - notification.content = `${event.eventName} is updated!` - notification.tag = 'Update' - notificationHelper.addToNotificationForAll(req, res, notification, next) + const newNotif = this.pushNotification( + 'Event update!', + `${event.eventName} is updated!`, + TAGS.UPDATE + ) + notificationHelper.addToNotificationForAll(req, res, newNotif, next) res.status(HttpStatus.OK).json({ event: event }) } catch (error) { HANDLER.handleError(res, error) } - }, + } - rsvp: async (req, res, next) => { + async rsvp (req, res, next) { const { yes, no, maybe } = req.body const { id } = req.params - notification.tag = 'RSVP' try { - const data = await Event.findById(id) + const data = await this.EventModel.findById(id) if (!data) { res.status(HttpStatus.BAD_REQUEST).json({ error: 'No Event is available' }) return @@ -73,21 +95,27 @@ module.exports = { data.rsvpNo.includes(req.user.id) || data.rsvpYes.includes(req.user.id)) { req.io.emit('already rsvp', { data: 'You have already done the rsvp' }) - notification.heading = 'Already rsvp!' - notification.content = 'You have already done the rsvp' - notificationHelper.addToNotificationForUser(req.user._id, res, notification, next) + const newNotif = this.pushNotification( + 'Already rsvp!', + 'You have already done the rsvp', + TAGS.RSVP + ) + notificationHelper.addToNotificationForUser(req.user._id, res, newNotif, next) res.status(HttpStatus.OK).json({ msg: 'You have already done the rsvp' }) return } - const event = await Event.findByIdAndUpdate(id) + const event = await this.EventModel.findByIdAndUpdate(id) + const newNotif = this.pushNotification( + 'RSVP done!', + 'RSVP successfully done!', + TAGS.RSVP + ) if (yes) { try { event.rsvpYes.push(req.user.id) await event.save() req.io.emit('rsvp done', { data: 'RSVP successfully done!' }) - notification.heading = 'RSVP done!' - notification.content = 'RSVP successfully done!' - notificationHelper.addToNotificationForUser(req.user._id, res, notification, next) + notificationHelper.addToNotificationForUser(req.user._id, res, newNotif, next) res.status(HttpStatus.OK).json({ rsvpData: data }) } catch (error) { return res.status(HttpStatus.BAD_REQUEST).json({ error: error }) @@ -98,9 +126,7 @@ module.exports = { event.rsvpNo.push(req.user.id) await event.save() req.io.emit('rsvp done', { data: 'RSVP successfully done!' }) - notification.heading = 'RSVP done!' - notification.content = 'RSVP successfully done!' - notificationHelper.addToNotificationForUser(req.user._id, res, notification, next) + notificationHelper.addToNotificationForUser(req.user._id, res, newNotif, next) res.status(HttpStatus.OK).json({ rsvpData: data }) } catch (error) { return res.status(HttpStatus.BAD_REQUEST).json({ error: error }) @@ -111,9 +137,7 @@ module.exports = { event.rsvpMaybe.push(req.user.id) await event.save() req.io.emit('rsvp done', { data: 'RSVP successfully done!' }) - notification.heading = 'RSVP done!' - notification.content = 'RSVP successfully done!' - notificationHelper.addToNotificationForUser(req.user._id, res, notification, next) + notificationHelper.addToNotificationForUser(req.user._id, res, newNotif, next) res.status(HttpStatus.OK).json({ rsvpData: data }) } catch (error) { return res.status(HttpStatus.BAD_REQUEST).json({ error: error }) @@ -122,12 +146,12 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - GetEventById: async (req, res, next) => { + async GetEventById (req, res, next) { const { id } = req.params try { - const EventData = await Event.findById(id) + const EventData = await this.EventModel.findById(id) if (!EventData) { return res.status(HttpStatus.NOT_FOUND).json({ error: 'No such Event is available!' }) } @@ -135,11 +159,11 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - GetAllEvent: async (req, res, next) => { + async GetAllEvent (req, res, next) { try { - const EventData = await Event.find({}, {}, helper.paginate(req)) + const EventData = await this.EventModel.find({}, {}, helper.paginate(req)) .populate('createdBy', ['name.firstName', 'name.lastName', '_id', 'isAdmin']) .sort({ eventDate: -1 }) .lean() @@ -147,44 +171,50 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - deleteEvent: async (req, res, next) => { + async deleteEvent (req, res, next) { const { id } = req.params try { - const deleteEvent = await Event.findById(id) + const deleteEvent = await this.EventModel.findById(id) if (!deleteEvent) { return res.status(HttpStatus.NOT_FOUND).json({ message: 'No Event exists' }) } if (permission.check(req, res, deleteEvent.createdBy)) { await Event.findByIdAndRemove(id) req.io.emit('event deleted', { data: deleteEvent.eventName }) - notification.heading = 'Event deleted!' - notification.content = `Event ${deleteEvent.eventName} is deleted!` - notification.tag = 'Deleted' - notificationHelper.addToNotificationForAll(req, res, notification, next) + const newNotif = this.pushNotification( + 'Event deleted!', + `Event ${deleteEvent.eventName} is deleted!`, + TAGS.DELETE + ) + notificationHelper.addToNotificationForAll(req, res, newNotif, next) return res.status(HttpStatus.OK).json({ deleteEvent: deleteEvent, message: 'Deleted the event' }) } return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Not permitted!' }) } catch (error) { HANDLER.handleError(res, error) } - }, + } - UpComingEvents: async (req, res, next) => { + async UpComingEvents (req, res, next) { try { - const events = await Event.find({ eventDate: { $gt: Date.now() } }, {}, helper.paginate(req)) + const events = await this.EventModel.find({ + eventDate: { + $gt: Date.now() + } + }, {}, helper.paginate(req)) .sort({ eventDate: -1 }) .exec() return res.status(HttpStatus.OK).json({ events }) } catch (error) { HANDLER.handleError(res, next) } - }, + } - getAllEventByUser: async (req, res, next) => { + async getAllEventByUser (req, res, next) { try { - const events = await Event.find({ createdBy: req.user._id }, {}, helper.paginate(req)) + const events = await this.EventModel.find({ createdBy: req.user._id }, {}, helper.paginate(req)) .sort({ eventDate: -1 }) .populate('createdBy', '_id name.firstName name.lastName') .exec() @@ -194,3 +224,5 @@ module.exports = { } } } + +module.exports = EventClass diff --git a/app/controllers/notification.js b/app/controllers/notification.js index 7fd4027..ebd3f51 100644 --- a/app/controllers/notification.js +++ b/app/controllers/notification.js @@ -5,11 +5,30 @@ const helper = require('../utils/paginate') const User = require('../models/User') const ProposalNotifications = require('../models/ProposalNotification') -module.exports = { +class NotificationProvider { + constructor(NotificationModel, UserModel, ProposalModel) { + this.#initModels(NotificationModel, UserModel, ProposalModel) + this.#initBinding() + } + + // PRIVATE ES6 + #initModels = (NotificationModel, UserModel, ProposalModel) => { + this.UserModel = UserModel + this.NotificationModel = NotificationModel + this.ProposalModel = ProposalModel + } + + // PRIVATE ES6 + #initBinding = () => { + this.getOrgNotifications = this.getOrgNotifications.bind(this) + this.getUserNotification = this.getUserNotification.bind(this) + this.getProposalNotifications = this.getProposalNotifications.bind(this) + } + // GET ALL THE NOTIFICATIONS FOR ALL - getOrgNotifications: async (req, res, next) => { + async getOrgNotifications(req, res, next) { try { - const notifications = await Notifications.find( + const notifications = await this.NotificationModel.find( {}, {}, helper.paginate(req) @@ -21,12 +40,13 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } + // GET LOGGED IN USER NOTIFICATIONS - getUserNotification: async (req, res, next) => { + async getUserNotification(req, res, next) { const userId = req.user._id try { - const user = await User.findById(userId) + const user = await this.UserModel.findById(userId) if (!user) { return res .status(HttpStatus.BAD_REQUEST) @@ -41,14 +61,16 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - getProposalNotifications: async (req, res, next) => { + async getProposalNotifications(req, res, next) { try { - const notifications = await ProposalNotifications.find({}) + const notifications = await this.ProposalModel.find({}) return res.status(HttpStatus.OK).json({ notifications }) } catch (error) { HANDLER.handleError(res, error) } } } + +module.exports = NotificationProvider diff --git a/app/controllers/organization.js b/app/controllers/organization.js index f6c2ecc..7a2516b 100644 --- a/app/controllers/organization.js +++ b/app/controllers/organization.js @@ -9,14 +9,13 @@ const Project = require('../models/Project') const Event = require('../models/Event') const permission = require('../utils/permission') const TAGS = require('../utils/notificationTags') -const notification = { - heading: '', - content: '', - tag: '' -} +const Notification = require('../utils/notificationClass') -module.exports = { - createOrganization: async (req, res, next) => { +class OrganizationClass extends Notification { + constructor() { + super() + } + async createOrganization (req, res, next) { const org = new Organization(req.body) if (req.file) { helper.mapToDb(req, org) @@ -24,17 +23,19 @@ module.exports = { try { const orgData = await org.save() req.io.emit('new org created', { data: orgData.name }) - notification.heading = 'New org!' - notification.content = `${orgData.name} is created!` - notification.tag = TAGS.NEW - notificationHelper.addToNotificationForAll(req, res, notification, next) + const newNotif = this.pushNotification( + 'New org!', + `${orgData.name} is created!`, + TAGS.NEW + ) + notificationHelper.addToNotificationForAll(req, res, newNotif, next) return res.status(HttpStatus.CREATED).json({ orgData }) } catch (error) { HANDLER.handleError(res, error) } - }, + } - updateOrgDetails: async (req, res, next) => { + async updateOrgDetails (req, res, next) { const { id } = req.params const updates = Object.keys(req.body) const allowedUpdates = [ @@ -74,9 +75,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - getOrgDetailsById: async (req, res, next) => { + async getOrgDetailsById (req, res, next) { const { id } = req.params try { const orgData = await Organization.findById(id) @@ -104,9 +105,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - deleteOrg: async (req, res, next) => { + async deleteOrg (req, res, next) { const { id } = req.params try { const org = await Organization.findByIdAndRemove(id) @@ -122,17 +123,19 @@ module.exports = { .json({ msg: "You don't have the permission!" }) } req.io.emit('org deleted', { data: org.name }) - notification.heading = 'Org deleted!' - notification.content = `${org.name} is deleted!` - notification.tag = TAGS.DELETE - notificationHelper.addToNotificationForAll(req, res, notification, next) + const newNotif = this.pushNotification( + 'Org deleted!', + `${org.name} is deleted!`, + TAGS.DELETE + ) + notificationHelper.addToNotificationForAll(req, res, newNotif, next) return res.status(HttpStatus.OK).json({ organization: org }) } catch (error) { HANDLER.handleError(res, error) } - }, + } - archiveOrg: async (req, res, next) => { + async archiveOrg (req, res, next) { const { id } = req.params try { const org = await Organization.findById(id) @@ -147,9 +150,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - triggerMaintenance: async (req, res, next) => { + async triggerMaintenance (req, res, next) { const { id } = req.params try { const organization = await Organization.findById(id) @@ -167,12 +170,14 @@ module.exports = { // toggle maintenance mode organization.isMaintenance = !organization.isMaintenance await organization.save() - notification.tag = TAGS.MAINTENANCE if (organization.isMaintenance) { req.io.emit('org under maintenance', { data: organization.name }) - notification.heading = 'Maintenance mode on!' - notification.content = `${organization.name} is kept under maintenance!` + const newNotif = this.pushNotification( + 'Maintenance mode on!', + `${organization.name} is kept under maintenance!`, + TAGS.MAINTENANCE + ) notificationHelper.addToNotificationForAll(req, res, notification, next) return res.status(HttpStatus.OK).json({ maintenance: true, @@ -181,8 +186,11 @@ module.exports = { } req.io.emit('org revoked maintenance', { data: organization.name }) - notification.heading = 'Maintenance mode off!' - notification.content = `${organization.name} is revoked from maintenance!` + const newNotif = this.pushNotification( + 'Maintenance mode off!', + `${organization.name} is revoked from maintenance!`, + TAGS.MAINTENANCE + ) return res.status(HttpStatus.OK).json({ maintenance: false, msg: 'Organization is recovered from maintenance!!' @@ -195,9 +203,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - updateSettings: async (req, res, next) => { + async updateSettings (req, res, next) { const { id } = req.params try { // check if org exists @@ -234,8 +242,8 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, - getOrgOverView: async (req, res, next) => { + } + async getOrgOverView (req, res, next) { const orgOverView = {} try { const org = await Organization.find({}) @@ -250,9 +258,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // SEARCH FUNCTIONALITY - getMembers: async (req, res, next) => { + async getMembers (req, res, next) { try { const { search } = req.query if (search) { @@ -288,9 +296,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // REMOVE ADMIN - removeAdmin: async (req, res, next) => { + async removeAdmin (req, res, next) { try { const { userId, orgId } = req.params const org = await Organization.findById(orgId) @@ -328,3 +336,6 @@ module.exports = { } } } + +module.exports = OrganizationClass + diff --git a/app/controllers/post.js b/app/controllers/post.js index 5177ffd..ed76d7f 100644 --- a/app/controllers/post.js +++ b/app/controllers/post.js @@ -7,9 +7,9 @@ const permission = require('../utils/permission') const helper = require('../utils/paginate') const settingsHelper = require('../utils/settingHelpers') -module.exports = { +class PostClass { // CREATE POST - create: async (req, res, next) => { + async create(req, res, next) { const post = new PostModel(req.body) const userId = req.user.id.toString() post.userId = userId @@ -23,10 +23,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // DELETE POST - delete: async (req, res, next) => { + async delete(req, res, next) { const { id } = req.params try { const post = await PostModel.findById(id) @@ -45,10 +45,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // UPDATE POST - updatePost: async (req, res, next) => { + async updatePost(req, res, next) { const { id } = req.params const updates = Object.keys(req.body) const allowedUpdates = ['content', 'imgUrl'] @@ -87,10 +87,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // GET POST BY ID - getPostById: async (req, res, next) => { + async getPostById(req, res, next) { const { id } = req.params try { const post = await PostModel.findById(id) @@ -112,10 +112,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // GET ALL THE POSTS - getAllPost: async (req, res, next) => { + async getAllPost(req, res, next) { try { const posts = await PostModel.find({}, {}, helper.paginate(req)) .populate('userId', [ @@ -135,10 +135,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // UPVOTE POST - upvote: async (req, res, next) => { + async upvote(req, res, next) { const { id } = req.params const userId = req.user.id.toString() try { @@ -162,9 +162,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - getPostByUser: async (req, res, next) => { + async getPostByUser(req, res, next) { try { const posts = await PostModel.find( { userId: req.user._id }, @@ -184,10 +184,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // PIN THE POST - pinPost: async (req, res, next) => { + async pinPost(req, res, next) { const { id } = req.params try { const post = await PostModel.findById(id) @@ -215,10 +215,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // GET ALL PINNED POST - getPinned: async (req, res, next) => { + async getPinned(req, res, next) { try { const posts = await PostModel.find({}, {}, helper.paginate(req)) .populate('userId', [ @@ -240,3 +240,5 @@ module.exports = { } } } + +module.exports = PostClass diff --git a/app/controllers/project.js b/app/controllers/project.js index 39770ab..a9142e7 100644 --- a/app/controllers/project.js +++ b/app/controllers/project.js @@ -5,8 +5,9 @@ const helper = require('../utils/paginate') const permission = require('../utils/permission') const settingsHelper = require('../utils/settingHelpers') -module.exports = { - createProject: async (req, res, next) => { +class ProjectClass { + + async createProject (req, res, next) { try { const project = await new Project(req.body) project.createdBy = req.user._id @@ -15,8 +16,8 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, - getAllProjects: async (req, res, next) => { + } + async getAllProjects (req, res, next) { try { const projects = await Project.find({}, {}, helper.paginate(req)) .populate('createdBy', '_id name.firstName name.lastName email') @@ -26,8 +27,8 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, - getProjectById: async (req, res, next) => { + } + async getProjectById (req, res, next) { const { id } = req.params try { const project = await Project.findById(id) @@ -41,8 +42,8 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, - updateProject: async (req, res, next) => { + } + async updateProject (req, res, next) { const { id } = req.params const updates = Object.keys(req.body) const allowedUpdates = [ @@ -85,8 +86,8 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, - deleteProject: async (req, res, next) => { + } + async deleteProject (req, res, next) { const { id } = req.params try { const project = await Project.findById(id) @@ -102,8 +103,8 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, - projectCreatedByUser: async (req, res, next) => { + } + async projectCreatedByUser (req, res, next) { try { const { id } = req.user const projects = await Project.find({ createdBy: id }, {}, helper.paginate(req)) @@ -116,3 +117,5 @@ module.exports = { } } } + +module.exports = ProjectClass \ No newline at end of file diff --git a/app/controllers/proposal.js b/app/controllers/proposal.js index 3aab6bb..14f34da 100644 --- a/app/controllers/proposal.js +++ b/app/controllers/proposal.js @@ -5,10 +5,15 @@ const HttpStatus = require('http-status-codes') const AWS = require('aws-sdk') const TAGS = require('../utils/notificationTags') const proposalNotificationHelper = require('../utils/proposal-notif-helper') +const Notification = require('../utils/notificationClass') + +class ProposalClass extends Notification { + constructor() { + super() + } -module.exports = { // Creating a proposal - createProposal: async (req, res, next) => { + async createProposal(req, res, next) { const proposal = new ProposalModel(req.body) const creator = req.body.creator @@ -23,25 +28,21 @@ module.exports = { content: `New Proposal ${proposal.title} created by ${name}`, tag: TAGS.NEW }) - proposalNotificationHelper.addNotificationForAll( - req, - res, - { - heading: 'New Proposal Created', - content: `New Proposal ${proposal.title} created by ${name}`, - tag: TAGS.NEW - }, - next + const newNotif = this.pushNotification( + 'New Proposal Created', + `New Proposal ${proposal.title} created by ${name}`, + TAGS.NEW ) + proposalNotificationHelper.addNotificationForAll( req, res, newNotif, next) res.status(HttpStatus.CREATED).json({ proposal }) } catch (error) { HANDLER.handleError(res, error) } - }, + } // Updates the content of the proposal - saveProposal: async (req, res, next) => { + async saveProposal(req, res, next) { const { proposalId } = req.params const { content, title, description } = req.body @@ -60,10 +61,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // attaches a file to the given proposal - attachFile: (req, res, next) => { + attachFile (req, res, next) { const { proposalId } = req.params const file = req.file const s3FileURL = process.env.AWS_UPLOADED_FILE_URL_LINK @@ -106,10 +107,10 @@ module.exports = { res.send({ data }) } }) - }, + } // Get proposals by userId - getByUserId: async (req, res, next) => { + async getByUserId(req, res, next) { const { userId } = req.params try { @@ -124,10 +125,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // Delete proposal by proposalId - deleteById: async (req, res, next) => { + async deleteById(req, res, next) { try { const proposalId = req.body.proposalId @@ -137,14 +138,15 @@ module.exports = { const user = await UserModal.findById(creator) const name = `${user.name.firstName} ${user.name.lastName}` + const newNotif = this.pushNotification( + 'Proposal Deleted', + `Proposal: "${result.title}" deleted by ${name}`, + TAGS.NEW + ) proposalNotificationHelper.addNotificationForAll( req, res, - { - heading: 'Proposal Deleted', - content: `Proposal: "${result.title}" deleted by ${name}`, - tag: TAGS.NEW - }, + newNotif, next ) req.io.emit('proposal deleted', { @@ -157,10 +159,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // Changes the state of a given proposal - changeState: async (req, res, next) => { + async changeState(req, res, next) { const { proposalId } = req.params const proposalStatus = req.body.proposalStatus try { @@ -178,24 +180,25 @@ module.exports = { content: `Proposal ${proposal.title} was submitted for review`, tag: TAGS.NEW }) + const newNotif = this.pushNotification( + 'Proposal Submitted', + `Proposal "${proposal.title}" was submitted for review`, + TAGS.NEW + ) proposalNotificationHelper.addNotificationForAll( req, res, - { - heading: 'Proposal Submitted', - content: `Proposal "${proposal.title}" was submitted for review`, - tag: TAGS.NEW - }, + newNotif, next ) res.status(HttpStatus.OK).json({ proposal: proposal }) } catch (error) { HANDLER.handleError(res, error) } - }, + } // Obtains the proposal by given proposal ID - getProposalById: async (req, res, next) => { + async getProposalById(req, res, next) { const { proposalId } = req.params try { @@ -210,9 +213,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - getAllProposals: async (req, res, next) => { + async getAllProposals(req, res, next) { try { const proposals = await ProposalModel.find({}) if (!proposals.length) { @@ -224,9 +227,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - commentOnProposal: async (req, res, next) => { + async commentOnProposal(req, res, next) { const { proposalId, comment, userId, isAuthor, author } = req.body try { @@ -251,14 +254,15 @@ module.exports = { .json({ message: 'Proposal could not be found!' }) } if (!isAuthor) { + const newNotif = this.pushNotification( + 'New comment', + `New comments in your proposal "${updatedProposal.title}" by ${name}`, + TAGS.COMMENT + ) proposalNotificationHelper.addToNotificationForUser( author, res, - { - heading: 'New comment', - content: `New comments in your proposal "${updatedProposal.title}" by ${name}`, - tag: TAGS.COMMENT - }, + newNotif, next ) } @@ -267,9 +271,9 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } - getProposalNotificationsByUser: async (req, res, next) => { + async getProposalNotificationsByUser(req, res, next) { const userId = req.body.userId try { @@ -288,3 +292,5 @@ module.exports = { } } } + +module.exports = ProposalClass diff --git a/app/controllers/user.js b/app/controllers/user.js index 5cc134d..9032c96 100644 --- a/app/controllers/user.js +++ b/app/controllers/user.js @@ -1,28 +1,55 @@ -const User = require('../models/User') const jwt = require('jsonwebtoken') const HttpStatus = require('http-status-codes') const emailController = require('./email') const permission = require('../utils/permission') const HANDLER = require('../utils/response-helper') const notificationHelper = require('../utils/notif-helper') -const Projects = require('../models/Project') -const Events = require('../models/Event') -const Organization = require('../models/Organisation') const TAGS = require('../utils/notificationTags') const settingHelper = require('../utils/settingHelpers') -const notification = { - heading: '', - content: '', - tag: '' -} +const Notification = require('../utils/notificationClass') + +class UserController extends Notification { + constructor (User, Event, Project, Organisation) { + super() + this.#initModels(User, Event, Project, Organisation) + this.#initBinding() + } + + // INIT MODELS (PRIVATE) + #initModels = (UserModel, EventModel, ProjectModel, OrganisationModel) => { + this.UserModel = UserModel + this.EventModel = EventModel + this.ProjectModel = ProjectModel + this.OrganisationModel = OrganisationModel + } + + // BINDERS (PRIVATE) + #initBinding = () => { + this.createUser = this.createUser.bind(this) + this.userProfile = this.userProfile.bind(this) + this.userDelete = this.userDelete.bind(this) + this.activateAccount = this.activateAccount.bind(this) + this.addFollower = this.addFollower.bind(this) + this.addFollowing = this.addFollowing.bind(this) + this.removeFollower = this.removeFollower.bind(this) + this.removeFollowing = this.removeFollowing.bind(this) + this.blockUser = this.blockUser.bind(this) + this.unBlockUser = this.unBlockUser.bind(this) + this.deactivateAccount = this.deactivateAccount.bind(this) + this.getInviteLink = this.getInviteLink.bind(this) + this.processInvite = this.processInvite.bind(this) + this.forgotPasswordRequest = this.forgotPasswordRequest.bind(this) + this.getPersonalOverview = this.getPersonalOverview.bind(this) + this.logout = this.logout.bind(this) + this.updatePassword = this.updatePassword.bind(this) + } -module.exports = { // CREATE USER - createUser: async (req, res, next) => { - const user = new User(req.body) + async createUser (req, res, next) { + const user = new this.UserModel(req.body) try { - const isRegisteredUserExists = await User.findOne({ firstRegister: true }) - const Org = await Organization.find({}).lean().exec() + const isRegisteredUserExists = await this.UserModel.findOne({ firstRegister: true }) + const Org = await this.OrganisationModel.find({}).lean().exec() // for the first user who will be setting up the platform for their community if (!isRegisteredUserExists) { user.isAdmin = true @@ -42,9 +69,10 @@ module.exports = { } catch (error) { return res.status(HttpStatus.NOT_ACCEPTABLE).json({ error: error }) } - }, + } + // GET USER PROFILE - userProfile: async (req, res, next) => { + async userProfile (req, res, next) { try { const user = req.user if (!user) { @@ -54,16 +82,16 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // USER PROFILE UPDATE - userProfileUpdate: async (req, res, next) => { + async userProfileUpdate (req, res, next) { const updates = Object.keys(req.body) const allowedUpdates = [ 'phone', 'info', 'about', - 'isDeactivated' + 'socialMedia' ] // added control as per org settings if (settingHelper.canChangeName()) { @@ -89,13 +117,13 @@ module.exports = { } catch (error) { return res.status(HttpStatus.BAD_REQUEST).json({ error }) } - }, + } // FORGOT PASSWORD REQUEST - forgotPasswordRequest: async (req, res) => { + async forgotPasswordRequest (req, res) { const { email } = req.body try { - const user = await User.findOne({ email: email }) + const user = await this.UserModel.findOne({ email: email }) if (!user) { return res.status(HttpStatus.NOT_FOUND).json({ msg: 'User not found!' }) } @@ -105,16 +133,16 @@ module.exports = { } catch (error) { return res.status(HttpStatus.BAD_REQUEST).json({ error }) } - }, + } - updatePassword: async (req, res, next) => { + async updatePassword (req, res, next) { const { password, id } = req.body const { token } = req.params try { const decodedToken = jwt.verify(token, process.env.JWT_SECRET) if (Date.now() <= decodedToken.expiry) { - const user = await User.findById({ + const user = await this.UserModel.findById({ _id: id }) if (!user) { @@ -126,10 +154,11 @@ module.exports = { userId: user._id } req.io.emit('Password update', obj) - notification.heading = 'Forgot password!' - notification.content = 'Password successfully updated!' - notification.tag = TAGS.UPDATE - await notificationHelper.addToNotificationForUser(id, res, notification, next) + const newNotif = this.pushNotification( + 'Forgot password!', + 'Password successfully updated!', + TAGS.UPDATE) + await notificationHelper.addToNotificationForUser(id, res, newNotif, next) return res.status(HttpStatus.OK).json({ updated: true }) } else { res.status(HttpStatus.BAD_REQUEST).json({ error: 'Token expired' }) @@ -137,10 +166,10 @@ module.exports = { } catch (error) { res.status(HttpStatus.BAD_REQUEST).json({ error }) } - }, + } // LOGOUT USER - logout: async (req, res, next) => { + async logout (req, res, next) { try { req.user.tokens = [] await req.user.save() @@ -148,10 +177,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // REMOVE USER - userDelete: async (req, res, next) => { + async userDelete (req, res, next) { try { if (permission.check(req, res)) { await req.user.remove() @@ -161,16 +190,16 @@ module.exports = { } catch (error) { return res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ error }) } - }, + } // USER ACCOUNT ACTIVATION - activateAccount: async (req, res, next) => { + async activateAccount (req, res, next) { try { const { token } = req.params const decodedToken = jwt.verify(token, 'process.env.JWT_SECRET') const expiryTime = decodedToken.iat + 24 * 3600 * 1000 // 24 hrs if (expiryTime <= Date.now()) { - const user = await User.findById(decodedToken._id) + const user = await this.UserModel.findById(decodedToken._id) if (!user) { return res.status(HttpStatus.NOT_FOUND).json({ msg: 'User not found!' }) } @@ -181,19 +210,21 @@ module.exports = { userId: user._id } req.io.emit('Account activate', obj) - notification.heading = 'Account activate!' - notification.content = 'Account successfully activated!' - notification.tag = TAGS.ACTIVATE - await notificationHelper.addToNotificationForUser(user._id, res, notification, next) + const newNotif = this.pushNotification( + 'Account activate!', + 'Account successfully activated!', + TAGS.ACTIVATE + ) + await notificationHelper.addToNotificationForUser(user._id, res, newNotif, next) return res.status(HttpStatus.OK).json({ msg: 'Succesfully activated!' }) } } catch (Error) { return res.status(HttpStatus.BAD_REQUEST).json({ Error }) } - }, + } // GET INVITE LINK - getInviteLink: async (req, res, next) => { + async getInviteLink (req, res, next) { try { const { role } = req.query const token = jwt.sign({ _id: req.user._id, role: role, expiry: Date.now() + 24 * 3600 * 1000 }, process.env.JWT_SECRET) @@ -202,15 +233,15 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // PROCESS THE INVITE LINK - processInvite: async (req, res, next) => { + async processInvite (req, res, next) { try { const { token } = req.params const decodedToken = jwt.verify(token, process.env.JWT_SECRET) // check if token not expired and sender exist in db then valid request - const user = await User.findById(decodedToken._id) + const user = await this.UserModel.findById(decodedToken._id) if (user && Date.now() <= decodedToken.expiry) { console.log('Valid invite!') if (decodedToken.role === 'user') { @@ -219,23 +250,23 @@ module.exports = { } if (decodedToken.role === 'admin') { // TODO: CHANGE THE URL IN PRODUCTION (in env file) - return res.redirect(`${process.env.clientbaseurl}/admin`) + return res.redirect(`${process.env.clientbaseurl}admin`) } } return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Invalid token!' }) } catch (error) { HANDLER.handleError(res, error) } - }, + } // ADD TO THE FOLLOWINGS LIST - addFollowing: async (req, res, next) => { + async addFollowing (req, res, next) { const { followId } = req.body try { if (followId === req.user._id) { return res.status(HttpStatus.OK).json({ msg: 'You can not follow yourself!' }) } - const user = await User.findById(req.user.id) + const user = await this.UserModel.findById(req.user.id) if (!user) { return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'No such user exists!' }) } @@ -245,13 +276,13 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // ADD TO FOLLOWERS LIST - addFollower: async (req, res, next) => { + async addFollower (req, res, next) { const { followId } = req.body try { - const user = await User.findById(followId) + const user = await this.UserModel.findById(followId) if (!user) { return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'No such user exists!' }) } @@ -263,11 +294,13 @@ module.exports = { followId: user._id } req.io.emit('New follower', obj) - notification.heading = 'New follower!' - notification.content = `${req.user.name.firstName} started following you!` - notification.tag = TAGS.FOLLOWER - await notificationHelper.addToNotificationForUser(user._id, res, notification, next) - const userData = await User.findById(req.user._id) + const newNotif = this.pushNotification( + 'New follower!', + `${req.user.name.firstName} started following you!`, + TAGS.FOLLOWER + ) + await notificationHelper.addToNotificationForUser(user._id, res, newNotif, next) + const userData = await this.UserModel.findById(req.user._id) .populate('followings', ['name.firstName', 'name.lastName', 'info.about.designation', '_id', 'isAdmin']) .populate('followers', ['name.firstName', 'name.lastName', 'info.about.designation', '_id', 'isAdmin']) .populate('blocked', ['name.firstName', 'name.lastName', 'info.about.designation', '_id', 'isAdmin']) @@ -276,13 +309,13 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // REMOVE FROM FOLLOWINGS LIST - removeFollowing: async (req, res, next) => { + async removeFollowing (req, res, next) { const { followId } = req.body try { - const user = await User.findById(req.user._id) + const user = await this.UserModel.findById(req.user._id) if (!user) { return res.status(HttpStatus.OK).json({ msg: 'No such user exists!' }) } @@ -300,13 +333,13 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // REMOVE FROM FOLLOWERS LIST - removeFollower: async (req, res, next) => { + async removeFollower (req, res, next) { const { followId } = req.body try { - const user = await User.findById(followId) + const user = await this.UserModel.findById(followId) if (!user) { return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such user exists!' }) } @@ -317,7 +350,7 @@ module.exports = { } user.followers.splice(isFollowingIndex, 1) await user.save() - const userData = await User.findById(req.user._id) + const userData = await this.UserModel.findById(req.user._id) .populate('followings', ['name.firstName', 'name.lastName', 'info.about.designation', '_id', 'isAdmin']) .populate('followers', ['name.firstName', 'name.lastName', 'info.about.designation', '_id', 'isAdmin']) .populate('blocked', ['name.firstName', 'name.lastName', 'info.about.designation', '_id', 'isAdmin']) @@ -326,13 +359,13 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // BLOCK THE USER - blockUser: async (req, res, next) => { + async blockUser (req, res, next) { const { id } = req.params try { - const user = await User.findById(req.user._id) + const user = await this.UserModel.findById(req.user._id) .populate('blocked', ['name.firstName', 'name.lastName', 'email']) .exec() if (!user) { @@ -349,13 +382,13 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // UNBLOCK USER - unBlockUser: async (req, res, next) => { + async unBlockUser (req, res, next) { const { id } = req.params try { - const user = await User.findById(req.user._id) + const user = await this.UserModel.findById(req.user._id) .populate('blocked', ['name.firstName', 'name.lastName', 'email']) .exec() if (!user) { @@ -376,26 +409,26 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } // GET OVERALL PERSONAL OVERVIEW - getPersonalOverview: async (req, res, next) => { + async getPersonalOverview (req, res, next) { const userId = req.user._id const personalOverview = {} try { - personalOverview.projects = await Projects.find({ createdBy: userId }).estimatedDocumentCount() - personalOverview.events = await Events.find({ createdBy: userId }).estimatedDocumentCount() + personalOverview.projects = await this.ProjectModel.find({ createdBy: userId }).estimatedDocumentCount() + personalOverview.events = await this.EventModel.find({ createdBy: userId }).estimatedDocumentCount() return res.status(HttpStatus.OK).json({ personalOverview }) } catch (error) { HANDLER.handleError(req, error) } - }, + } // REMOVE USER - removeUser: async (req, res, next) => { + async removeUser (req, res, next) { const { id } = req.params try { - const user = await User.findById(id) + const user = await this.UserModel.findById(id) if (!user) { return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such user exits!' }) } @@ -409,9 +442,10 @@ module.exports = { } catch (error) { HANDLER.handleError(res, error) } - }, + } + // DEACTIVATE ACCOUNT (BY USER ITSELF) - deactivateAccount: async (req, res, next) => { + async deactivateAccount (req, res, next) { try { req.user.isActivated = !req.user.isActivated const user = await req.user.save() @@ -421,3 +455,5 @@ module.exports = { } } } + +module.exports = UserController diff --git a/app/routes/auth.js b/app/routes/auth.js index f42fd96..ed7c9ba 100644 --- a/app/routes/auth.js +++ b/app/routes/auth.js @@ -1,6 +1,8 @@ const express = require('express') const router = express.Router() -const authController = require('../controllers/auth') +const User = require('../models/User') +const AuthClass = require('../controllers/auth') +const authController = new AuthClass(User) // const isActivated = require('../middleware/activate') const isUnderMaintenance = require('../middleware/maintenance') diff --git a/app/routes/comment.js b/app/routes/comment.js index 5d16b55..cbff065 100644 --- a/app/routes/comment.js +++ b/app/routes/comment.js @@ -1,8 +1,10 @@ const express = require('express') const router = express.Router() const auth = require('../middleware/auth') -const commentController = require('../controllers/comment') const isUnderMaintenance = require('../middleware/maintenance') +const CommentModel = require('../models/Comment') +const CommentClass = require('../controllers/comment') +const commentController = new CommentClass(CommentModel) // CREATE COMMENT router.post( diff --git a/app/routes/event.js b/app/routes/event.js index 0d0dc02..46e7dcd 100644 --- a/app/routes/event.js +++ b/app/routes/event.js @@ -1,7 +1,9 @@ const express = require('express') const auth = require('../middleware/auth') const router = express.Router() -const eventController = require('../controllers/event') +const Event = require('../models/Event') +const EventClass = require('../controllers/event') +const eventController = new EventClass(Event) const isUnderMaintenance = require('../middleware/maintenance') // get all the events diff --git a/app/routes/notification.js b/app/routes/notification.js index 58152bd..366f673 100644 --- a/app/routes/notification.js +++ b/app/routes/notification.js @@ -2,7 +2,12 @@ const express = require('express') const router = express.Router() const auth = require('../middleware/auth') const isUnderMaintenance = require('../middleware/maintenance') -const notificationController = require('../controllers/notification') +const Notifications = require('../models/Notifications') +const User = require('../models/User') +const ProposalNotifications = require('../models/ProposalNotification') +const NotificationClass = require('../controllers/notification') +const notificationController = new NotificationClass(Notifications, User, ProposalNotifications) + // GET NOTIFICATIONS FOR ALL router.get( @@ -21,6 +26,11 @@ router.get( ) // GET NOTICATIONS FOR PROPOSALS -router.get('/proposal/all', notificationController.getProposalNotifications) +router.get( + '/proposal/all', + isUnderMaintenance, + auth, + notificationController.getProposalNotifications +) module.exports = router diff --git a/app/routes/organisation.js b/app/routes/organisation.js index a69abc9..4c0a545 100644 --- a/app/routes/organisation.js +++ b/app/routes/organisation.js @@ -1,9 +1,10 @@ const express = require('express') const router = express.Router() const auth = require('../middleware/auth') -const OrgController = require('../controllers/organization') const uploader = require('../utils/uploader') const isUnderMaintenance = require('../middleware/maintenance') +const OrganizationClass = require('../controllers/organization') +const OrgController = new OrganizationClass() // CREATE ORG router.post( diff --git a/app/routes/post.js b/app/routes/post.js index 0208282..86617f0 100644 --- a/app/routes/post.js +++ b/app/routes/post.js @@ -1,10 +1,11 @@ require('../../config/mongoose') const express = require('express') const router = express.Router() -const postController = require('../controllers/post') const uploader = require('../utils/uploader') const auth = require('../middleware/auth') const isUnderMaintenance = require('../middleware/maintenance') +const PostClass = require('../controllers/post') +const postController = new PostClass() // CREATE A POST router.post( diff --git a/app/routes/project.js b/app/routes/project.js index 178a3f6..ae12178 100644 --- a/app/routes/project.js +++ b/app/routes/project.js @@ -1,8 +1,10 @@ const express = require('express') -const projectController = require('../controllers/project') const router = express.Router() const auth = require('../middleware/auth') const isUnderMaintenance = require('../middleware/maintenance') +const ProjectClass = require('../controllers/project') +const projectController = new ProjectClass() + // ADD PROJECT router.post( diff --git a/app/routes/proposal.js b/app/routes/proposal.js index 4a3650c..724dbfe 100644 --- a/app/routes/proposal.js +++ b/app/routes/proposal.js @@ -1,6 +1,7 @@ const express = require('express') const router = express.Router() -const proposalController = require('../controllers/proposal') +const ProposalClass = require('../controllers/proposal') +const proposalController = new ProposalClass() // Create a new proposal router.post('/', proposalController.createProposal) diff --git a/app/routes/user.js b/app/routes/user.js index ee6f609..0e1b521 100644 --- a/app/routes/user.js +++ b/app/routes/user.js @@ -1,9 +1,14 @@ const express = require('express') const router = express.Router() -const userController = require('../controllers/user') +const User = require('../models/User') +const Projects = require('../models/Project') +const Events = require('../models/Event') +const Organization = require('../models/Organisation') const auth = require('../middleware/auth') const isUnderMaintenance = require('../middleware/maintenance') // const email = require('../middleware/email') +const UserClass = require('../controllers/user') +const userController = new UserClass(User, Events, Projects, Organization) // create a user router.post( diff --git a/app/utils/notificationClass.js b/app/utils/notificationClass.js new file mode 100644 index 0000000..bfa2524 --- /dev/null +++ b/app/utils/notificationClass.js @@ -0,0 +1,14 @@ +module.exports = class Notification { + constructor (heading = '', content = '', tag = '') { + this.pushNotification(heading, content, tag) + } + + pushNotification (heading, content, tag) { + const notification = { + heading: heading, + content: content, + tag: tag + } + return notification + } +} diff --git a/config/mongoose.js b/config/mongoose.js index 25aa95b..a0bfc8a 100644 --- a/config/mongoose.js +++ b/config/mongoose.js @@ -1,15 +1,24 @@ const mongoose = require('mongoose') +class Connection { + constructor () { + console.log('DATABSE_URL ', process.env.DATABASE_URL) + this.url = `${process.env.DATABASE_URL}` + } -mongoose - .connect(process.env.DATABASE_URL, { - useNewUrlParser: true, - useCreateIndex: true, - useUnifiedTopology: true, - useFindAndModify: false - }) - .then(() => { - console.log('mongodb connection successful') - }) - .catch((err) => { - console.log('mongodb connection error', err) - }) + connect () { + mongoose.Promise = global.Promise + mongoose.set('useNewUrlParser', true) + mongoose.set('useFindAndModify', false) + mongoose.set('useCreateIndex', true) + mongoose.set('useUnifiedTopology', true) + mongoose.connect(this.url) + .then(() => { + console.log('mongodb connection successful') + }) + .catch((err) => { + console.log('mongodb connection error', err) + }) + } +} +// SINGLETON CLASS +module.exports = new Connection()