Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added update restrictions, techStacks in project and orgId to a user #147

Merged
merged 3 commits into from
Jul 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ JWT_SECRET="thisismysupersecrettokenjustkidding"
DATABASE_URL="mongodb://mongo:27017/donut-development"
SENDGRID_API_KEY='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'
SOCKET_PORT=8810
clientbaseurl = "http://localhost:3000/"
6 changes: 6 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ app.use(function (err, req, res, next) {
// 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()
})

module.exports = { app, io }
4 changes: 2 additions & 2 deletions app/controllers/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ module.exports = {
})
comment.votes.upVotes.user.unshift(userId)
await comment.save()
res.status(HttpStatus.OK).json({ comment: comment })
return res.status(HttpStatus.OK).json({ comment: comment })
} catch (error) {
HANDLER.handleError(res, error)
}
Expand Down Expand Up @@ -143,7 +143,7 @@ module.exports = {
})
comment.votes.downVotes.user.unshift(userId)
await comment.save()
res.status(HttpStatus.OK).json({ comment: comment })
return res.status(HttpStatus.OK).json({ comment: comment })
} catch (error) {
HANDLER.handleError(res, error)
}
Expand Down
14 changes: 11 additions & 3 deletions app/controllers/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const HttpStatus = require('http-status-codes')
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: '',
Expand Down Expand Up @@ -33,10 +34,17 @@ module.exports = {
try {
const event = await Event.findById(id)
if (!event) {
return res.status(HttpStatus.BAD_REQUEST).json({ message: 'No post exists' })
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'No post exists' })
}
// check for permission (TODO AFTER PREVIOUS PR MERGED)
updates.forEach(update => {
// check for permission and edit permission
if (!permission.check(req, res, event.createdBy) || (!settingsHelper.canEdit())) {
return res.status(HttpStatus.FORBIDDEN).json({ msg: 'Bad update request' })
}
// if edit allowed check allowed limit time
if (!settingsHelper.isEditAllowedNow(event.createdAt)) {
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Edit limit expired!' })
}
updates.forEach((update) => {
event[update] = req.body[update]
})
await event.save()
Expand Down
43 changes: 19 additions & 24 deletions app/controllers/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const Organization = require('../models/Organisation')
const HANDLER = require('../utils/response-helper')
const HttpStatus = require('http-status-codes')
const helper = require('../utils/uploader')
const paginater = require('../utils/paginate')
const notificationHelper = require('../utils/notif-helper')
const User = require('../models/User')
const Project = require('../models/Project')
Expand Down Expand Up @@ -69,7 +70,7 @@ module.exports = {
helper.mapToDb(req, org)
}
await org.save()
res.status(HttpStatus.OK).json({ organization: org })
return res.status(HttpStatus.OK).json({ organization: org })
} catch (error) {
HANDLER.handleError(res, error)
}
Expand Down Expand Up @@ -172,23 +173,20 @@ module.exports = {
req.io.emit('org under maintenance', { data: organization.name })
notification.heading = 'Maintenance mode on!'
notification.content = `${organization.name} is kept under maintenance!`
notificationHelper.addToNotificationForAll(
req,
res,
notification,
next
)
return res
.status(HttpStatus.OK)
.json({ msg: 'Organization is kept under the maintenance!!' })
notificationHelper.addToNotificationForAll(req, res, notification, next)
return res.status(HttpStatus.OK).json({
maintenance: true,
msg: 'Organization is kept under the maintenance!!'
})
}

req.io.emit('org revoked maintenance', { data: organization.name })
notification.heading = 'Maintenance mode off!'
notification.content = `${organization.name} is revoked from maintenance!`
return res
.status(HttpStatus.OK)
.json({ msg: 'Organization is recovered from maintenance!!' })
return res.status(HttpStatus.OK).json({
maintenance: false,
msg: 'Organization is recovered from maintenance!!'
})
} else {
return res
.status(HttpStatus.BAD_REQUEST)
Expand All @@ -209,15 +207,11 @@ module.exports = {
.status(HttpStatus.NOT_FOUND)
.json({ msg: 'No Organization found!' })
}
// check if user is admin or not
const adminIds = organization.adminInfo.adminId
const isAdmin = adminIds.indexOf(req.user.id)
const updates = Object.keys(req.body)
console.log('req.body ', req.body)
console.log('isAdmin ', isAdmin)
const allowedUpdates = ['settings', 'permissions', 'authentication']
// if admin then check if valid update
if (isAdmin !== -1) {
if (req.user.isAdmin === true) {
const isValidOperation = updates.every((update) => {
return allowedUpdates.includes(update)
})
Expand All @@ -227,9 +221,7 @@ module.exports = {
organization.options[update] = req.body[update]
})
await organization.save()
return res
.status(HttpStatus.OK)
.json({ msg: 'Successfully updated!' })
return res.status(HttpStatus.OK).json({ organization })
}
// invalid update
return res
Expand Down Expand Up @@ -272,8 +264,8 @@ module.exports = {
{ 'name.firstName': { $regex: regex } },
{ 'name.lastName': { $regex: regex } }
]
})
.select('name email isAdmin info.about.designation isRemoved')
}, {}, paginater.paginate(req))
.select('name email isAdmin info.about.designation isRemoved createdAt')
.lean()
.sort({ createdAt: -1 })
.exec()
Expand All @@ -282,7 +274,7 @@ module.exports = {
}
return res.status(HttpStatus.OK).json({ member })
} else {
const members = await User.find({})
const members = await User.find({}, {}, paginater.paginate(req))
.select('name email isAdmin info.about.designation isRemoved')
.lean()
.sort({ createdAt: -1 })
Expand Down Expand Up @@ -327,6 +319,9 @@ module.exports = {
await org.save()
// also make isAdmin false
const user = await User.findById(userId)
if (!user) {
return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such user exists!' })
}
user.isAdmin = false
await user.save()
return res.status(HttpStatus.OK).json({ org })
Expand Down
12 changes: 8 additions & 4 deletions app/controllers/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const HttpStatus = require('http-status-codes')
const imgUploadHelper = require('../utils/uploader')
const permission = require('../utils/permission')
const helper = require('../utils/paginate')
const settingsHelper = require('../utils/settingHelpers')

module.exports = {
// CREATE POST
Expand Down Expand Up @@ -67,10 +68,13 @@ module.exports = {
.status(HttpStatus.BAD_REQUEST)
.json({ message: 'No post exists' })
}
if (!permission.check(req, res, post.userId)) {
return res
.status(HttpStatus.FORBIDDEN)
.json({ message: 'Bad update request' })
// permission check for admin and creator || edit allowed or not
if (!permission.check(req, res, post.userId) || (!settingsHelper.canEdit())) {
return res.status(HttpStatus.FORBIDDEN).json({ message: 'Bad update request' })
}
// if allowed edit limit check
if (!settingsHelper.isEditAllowedNow(post.createdAt)) {
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Edit limit expired!' })
}
updates.forEach((update) => {
post[update] = req.body[update]
Expand Down
10 changes: 10 additions & 0 deletions app/controllers/project.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const HANDLER = require('../utils/response-helper')
const HttpStatus = require('http-status-codes')
const helper = require('../utils/paginate')
const permission = require('../utils/permission')
const settingsHelper = require('../utils/settingHelpers')

module.exports = {
createProject: async (req, res, next) => {
Expand Down Expand Up @@ -64,6 +65,15 @@ module.exports = {
if (!project) {
return res.status(HttpStatus.NOT_FOUND).json({ msg: 'No such project exits!' })
}
// permission check for admin and creator || is edit allowed
if (!permission.check(req, res, project.createdBy) || (!settingsHelper.canEdit())) {
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Bad Update Request!' })
}
// if allowed check edit limit
if (!settingsHelper.isEditAllowedNow(project.createdAt)) {
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Edit limit expired!' })
}
// check if valid edit
if (!isValidOperation) {
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Invalid update!' })
}
Expand Down
58 changes: 44 additions & 14 deletions app/controllers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ 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: '',
Expand All @@ -20,12 +22,19 @@ module.exports = {
const user = new User(req.body)
try {
const isRegisteredUserExists = await User.findOne({ firstRegister: true })
const Org = await Organization.find({}).lean().exec()
// for the first user who will be setting up the platform for their community
if (!isRegisteredUserExists) {
user.isAdmin = true
user.firstRegister = true
}
await user.save()
if (Org.length > 0) {
user.orgId = Org[0]._id
}
const data = await user.save()
if (!isRegisteredUserExists || req.body.isAdmin === true) {
settingHelper.addAdmin(data._id)
}
const token = await user.generateAuthToken()
// Added fn to send email to activate account with warm message
await emailController.sendEmail(req, res, next, token)
Expand All @@ -52,12 +61,17 @@ module.exports = {
userProfileUpdate: async (req, res, next) => {
const updates = Object.keys(req.body)
const allowedUpdates = [
'name',
'email',
'phone',
'info',
'about'
]
// added control as per org settings
if (settingHelper.canChangeName()) {
allowedUpdates.unshift('name')
}
if (settingHelper.canChangeEmail()) {
allowedUpdates.unshift('email')
}
const isValidOperation = updates.every((update) => {
return allowedUpdates.includes(update)
})
Expand Down Expand Up @@ -189,22 +203,38 @@ module.exports = {

// GET INVITE LINK
getInviteLink: async (req, res, next) => {
const token = jwt.sign({ _id: req.user._id, expiry: Date.now() + 24 * 3600 * 1000 }, process.env.JWT_SECRET)
const inviteLink = `${req.protocol}://${req.get('host')}/user/invite/${token}`
return res.status(HttpStatus.OK).json({ inviteLink: inviteLink })
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)
const inviteLink = `${req.protocol}://${req.get('host')}/user/invite/${token}`
return res.status(HttpStatus.OK).json({ inviteLink: inviteLink })
} catch (error) {
HANDLER.handleError(res, error)
}
},

// PROCESS THE INVITE LINK
processInvite: async (req, res, next) => {
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)
if (user && Date.now() <= decodedToken.expiry) {
console.log('Valid invite!')
return res.status(HttpStatus.OK).json({ success: true, msg: 'Redirect user to register in client side!' })
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)
if (user && Date.now() <= decodedToken.expiry) {
console.log('Valid invite!')
if (decodedToken.role === 'user') {
// TODO: CHANGE THE URL IN PRODUCTION (in env file)
return res.redirect(process.env.clientbaseurl)
}
if (decodedToken.role === 'admin') {
// TODO: CHANGE THE URL IN PRODUCTION (in env file)
return res.redirect(`${process.env.clientbaseurl}/admin`)
}
}
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Invalid token!' })
} catch (error) {
HANDLER.handleError(res, error)
}
return res.status(HttpStatus.BAD_REQUEST).json({ msg: 'Invalid token!' })
},

// ADD TO THE FOLLOWINGS LIST
Expand Down
8 changes: 8 additions & 0 deletions app/models/Organisation.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ const orgSchema = new Schema({
enum: ['English', 'French', 'German'],
default: 'English'
},
canEdit: {
type: Boolean,
default: true
},
editingLimit: {
type: String,
default: 'Always'
},
timeFormat: {
type: String,
enum: ['24', '12'],
Expand Down
1 change: 1 addition & 0 deletions app/models/Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const projectSchema = new Schema({
trim: true
}
},
techStacks: [],
image: {
type: Buffer,
contentType: String
Expand Down
9 changes: 7 additions & 2 deletions app/models/User.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const UserSchema = new mongoose.Schema({
twitter: {
type: String
},
instagram: {
github: {
type: String
},
linkedin: {
Expand Down Expand Up @@ -135,6 +135,10 @@ const UserSchema = new mongoose.Schema({
}
}
},
orgId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Organization'
},
notifications: [
{
heading: {
Expand Down Expand Up @@ -212,7 +216,8 @@ const UserSchema = new mongoose.Schema({
createdAt: {
type: Date,
required: true,
default: Date.now()
default: Date.now(),
select: true
},
updatedAt: {
type: Date,
Expand Down
Loading