-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuserController.js
More file actions
153 lines (113 loc) · 4.75 KB
/
userController.js
File metadata and controls
153 lines (113 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
const path = require('path')
const User = require('../models/userModel')
const Notification = require('../models/notificationModel')
const { removeFile, apiFeatures } = require('../utils')
const { catchAsync, appError } = require('./errorController')
// GET /api/users
exports.getAllUsers = catchAsync(async (req, res, next) => {
// const filter = {}
// if( req.query.search ) {
// filter.search = {
// $or: [
// { firstName: { $regex: req.query.search, $options: 'i' }},
// { lastName: { $regex: req.query.search, $options: 'i' }},
// { username: { $regex: req.query.search, $options: 'i' }},
// ]
// }
// }
// const users = await User.find({})
const users = await apiFeatures(User, req.query)
res.status(200).json({
status: 'success',
count: users.length,
data: users
})
})
// PATCH /api/users/:id/following (with protect middleware)
exports.following = catchAsync(async (req, res, next) => {
const profileUserId = req.params.id
const profileUser = await User.findById(profileUserId)
if(!profileUser) return next(appError('profile user not found by name'))
const logedInUser = req.session.user
const userId = logedInUser._id
const isFollowing = profileUser.followers?.includes(logedInUser._id)
const operator = isFollowing ? '$pull' : '$addToSet'
// Step-1: add profileUser._id to following array of logedInUser
const updatedUser = await User.findByIdAndUpdate(logedInUser._id, { [operator]: { following: profileUserId }}, { new: true })
req.session.user = updatedUser
// Step-2: add logedInUser._id to followers array of profileUser
const updatedProfileUser = await User.findByIdAndUpdate(profileUserId, { [operator]: { followers: logedInUser._id }} )
if( !isFollowing ) {
await Notification.insertNotification({
entityId: updatedUser._id, // on which notification user following ?
userFrom: userId, // Who following it ?
userTo: updatedUser.following.find(userId => userId === userId), // tweet.user._id, // which user create this tweet ?
type: 'follow', // ['like', 'retweet', 'replyTo', 'follow']
kind: 'user', // ['tweet', 'message', 'user' ]
})
}
res.status(201).json({
status: 'success',
// data: updatedUser
data: updatedProfileUser
})
})
// POST /api/users/avatar + protect + upload.single('avatar')
exports.userAvatarUpload = async(req, res, next) => {
try {
const userId = req.session.user._id
// remove project path:
const publicUrl = req.file.path.slice( process.cwd().length ) // start from length to end of string
// Remove existing picture after user updated, else removed the old user
removeFile(req.session.user.avatar)
const user = await User.findByIdAndUpdate(userId, { avatar: publicUrl }, { new: true, validate: true })
if(!user) return next(appError('update avatar failed'))
// if user modified then update session, so that logedInUser has updated data
req.session.user = user
res.status(201).json({
status: 'success',
data: user
})
} catch (err) {
// const publicUrl = req.file.path.slice( process.cwd().length ) // start from length to end of string
// removeFile(publicUrl)
next( appError(err.message) )
}
}
/* GET /upload/users/:avatar
When create any route rather than static route (like above we upload avatar) that
route not be accessable via client. So we have to create another route as though
image ask for another request to server, like 3rd party image or files does. */
exports.userAvatarRoute = (req, res, next) => {
try {
const avatar = req.params.avatar
const file = path.join( process.cwd(), 'upload', 'users', avatar)
res.sendFile(file)
} catch (err) {
next(appError(err.message))
}
}
// POST /api/users/coverPhoto + protect + upload.single('coverPhoto')
exports.userCoverPhotoUpload = async(req, res, next) => {
try {
if(!req.file) return next(appError('req.file is empty'))
const logedInUser = req.session.user
const userId = logedInUser._id
// remove project path:
const publicUrl = req.file.path.slice( process.cwd().length ) // start from length to end of string
// // Remove existing picture after user updated, else removed the old user
if(logedInUser.coverPhoto) removeFile(logedInUser.coverPhoto)
const updatedUser = await User.findByIdAndUpdate(userId, { coverPhoto: publicUrl }, { new: true, validate: true })
if(!updatedUser) return next(appError('update coverPhoto failed'))
// if user modified then update session, so that logedInUser has updated data
req.session.user = updatedUser
res.status(201).json({
status: 'success',
data: updatedUser
})
} catch (err) {
// const publicUrl = req.file.path.slice( process.cwd().length ) // start from length to end of string
// removeFile(publicUrl)
next( appError(err.message) )
}
}