-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.js
125 lines (107 loc) · 4.06 KB
/
server.js
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
require('dotenv').config();
const express = require('express'),
mongoose = require('mongoose'),
socketio = require('socket.io'),
helmet = require('helmet'),
hpp = require('hpp'),
path = require('path');
const port = process.env.PORT || 8080;
const User = require('./models/User');
const socketMain = require('./sockets/socketMain');
let app = express();
app.use(express.json({limit: '50mb'}));
app.use(helmet({contentSecurityPolicy: false}));
// app.use(helmet.contentSecurityPolicy({
// directives: {
// "default-src": ["'self'"],
// "connect-src": ["'self'", "'unsafe-inline'"],
// "img-src": ["'self'", "data:"],
// }
// }));
app.use(hpp());
// Mongo Connection
mongoose.connect(process.env.DB_URL, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false
})
.then(() => console.log('Connected to dB!'))
.catch(e => console.log(e));
const server = app.listen(port, process.env.IP, () => {
console.log(`Listening in port ${port}...`)
});
// Socket init
const io = socketio(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true
}
});
// Use API routes
const userRoutes = require('./routes/api/user'),
authRoutes = require('./routes/api/auth'),
messengerRoutes = require('./routes/api/messenger')(io);
app.use('/api/user', userRoutes);
app.use('/api/auth', authRoutes);
app.use('/messenger', messengerRoutes);
// Don't expose our internal server to the outside world.
// Serve static assets if in production
if(process.env.NODE_ENV === 'production') {
// Set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
io.on('connection', async (socket) => {
const userId = socket.handshake.query.userId;
// Update status and socket id of current user
await User.findByIdAndUpdate({_id: userId}, {
status: 'online',
$push: {socketId: socket.id}
}, {new: true});
// Emit notification to all online friends
const currUserFriends = await User.findOne({_id: userId}, {friends: 1, username: 1}).populate('friends', 'status socketId');
if(currUserFriends && currUserFriends.friends.length > 0) {
const onlineFriends = currUserFriends.friends.filter(friend => friend.status === 'online');
onlineFriends.forEach(friend => {
friend.socketId.forEach(socket => {
io.to(socket).emit('newOnlineFriend', {_id: userId, username: currUserFriends.username});
});
});
}
socketMain(io, socket, userId);
socket.on('disconnect', async (reason) => {
// Check if user has more than one connections
console.log(`Disconnecting ${userId}...`);
const foundUser = await User.findById({_id: userId}, {
friends: 1,
socketId: 1,
status: 1
},{new: true}).populate('friends', 'status socketId');
let updateUser;
if(foundUser && foundUser.socketId.length > 1) {
updateUser = await User.findByIdAndUpdate({_id: userId}, {$pull: {socketId: socket.id}}, {new: true});
console.log(`Disconnected ${userId}`);
} else {
updateUser = await User.findByIdAndUpdate({_id: userId}, {
status: 'offline',
$pull: {socketId: socket.id}
}, {new: true});
console.log(`Disconnected ${userId}`);
}
// Emit notification to all online friends
if(foundUser && foundUser.friends.length > 0 && updateUser.status === 'offline') {
const onlineFriends = foundUser.friends.filter(friend => friend.status === 'online');
onlineFriends.forEach(friend => {
friend.socketId.forEach(socket => {
io.to(socket).emit('newOfflineFriend', {_id: userId});
});
});
}
socket.disconnect(true);
});
});