-
Notifications
You must be signed in to change notification settings - Fork 0
/
user-service.ts
144 lines (117 loc) · 3.77 KB
/
user-service.ts
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
import bcyrpt from 'bcrypt';
import { ObjectId } from 'mongoose';
import { User, Notification } from '../mongo';
import { NewUser, UpdatedUserFields } from '../types';
import cloudinary from '../utils/cloudinary';
import SocketManager from '../utils/SocketManager';
const getUsers = async () => {
const users = await User.find({})
.select('-passwordHash')
.populate({
path: 'posts',
select: 'image createdAt updatedAt creator caption comments',
populate: {
path: 'creator',
select: 'username id image',
},
})
.populate('followers', { username: 1 })
.populate('following', { username: 1 });
return users;
};
const getUserById = async (id: string) => {
const user = await User.findById(id)
.select('-passwordHash')
.populate('posts', { image: 1 })
.populate('followers', { username: 1 })
.populate('following', { username: 1 });
return user;
};
const addUser = async (user: NewUser) => {
const existingUser = await User.findOne({ username: user.username });
if (existingUser) throw new Error('That username is already taken!');
if (user.password.length < 5) throw new Error('Password is too short!');
const passwordHash = await bcyrpt.hash(user.password, 10);
const newUser = new User({
fullName: user.fullName,
username: user.username,
email: user.email,
passwordHash,
});
const savedNewUser = await newUser.save();
return savedNewUser;
};
const updateUserById = async (user: UpdatedUserFields, id: string) => {
let passwordHash;
const updatedUser: any = { ...user };
if (user.password) {
passwordHash = await bcyrpt.hash(user.password, 10);
updatedUser.passwordHash = passwordHash;
delete updatedUser.password;
}
const savedUpdatedUser = await User.findByIdAndUpdate(id, updatedUser, { new: true })
.populate('posts', { image: 1 });
return savedUpdatedUser;
};
const followUserById = async (followerId: string, followedUserId: string) => {
const followedUser = await User.findById(followedUserId);
const follower = await User.findById(followerId);
if (!followedUser) {
throw new Error('User not found.');
}
// checking if user already follows the user they are requesting to follow
if (follower.following.map((ids: ObjectId) => ids?.toString()).includes(followedUser.id)) {
throw new Error('You already follow that user!');
}
followedUser.followers = [...followedUser.followers, follower];
follower.following = [...follower.following, followedUser.id];
await followedUser.save();
await follower.save();
await Notification.create({
type: 'follow',
creator: followerId,
entity: {
id: followerId,
model: 'User',
},
recipient: followedUserId,
hasBeenRead: false,
});
SocketManager.getInstance().emitNotification(followedUserId, 'follow');
};
const deleteUserImage = async (id: string) => {
const user = await User.findById(id);
cloudinary.destroy(user.image.publicId);
user.image = null;
await user.save();
return user;
};
const unfollowUserById = async (followerId: string, followedUserId: string) => {
const followedUser = await User.findById(followedUserId);
const follower = await User.findById(followerId);
if (!followedUser) {
throw new Error('User not found.');
}
follower.following = follower.following.filter(
(id: ObjectId) => id.toString() !== followedUser.id,
);
followedUser.followers = followedUser.followers.filter(
(id: ObjectId) => id.toString() !== follower.id,
);
await follower.save();
await followedUser.save();
await Notification.deleteOne({
type: 'follow',
creator: followerId,
recipient: followedUserId,
});
};
export default {
getUsers,
getUserById,
addUser,
updateUserById,
followUserById,
deleteUserImage,
unfollowUserById,
};