-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
215 lines (196 loc) · 6.42 KB
/
index.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
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
// Import libraries and app setup
require("dotenv").config();
const express = require("express");
const { v4: v4UniqueId } = require("uuid");
const http = require("http");
const { ExpressPeerServer } = require("peer");
const app = express();
const port = process.env.PORT || 7000;
const httpServer = http.Server(app);
const io = require("socket.io")(httpServer);
const peerServer = ExpressPeerServer(httpServer, {
debug: true,
});
const bcrypt = require("bcrypt");
const path = require("path");
const session = require("express-session");
const bodyParser = require("body-parser");
const AccountModel = require("./models/account");
const SESSION_NAME = process.env.SESSION_NAME;
const mongoose = require("mongoose");
app.set("view engine", "pug");
app.set("views", path.join(__dirname, "views"));
app.use(express.static("public"));
app.use("/peerjs", peerServer);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(
session({
name: SESSION_NAME,
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: { maxAge: 1000 * 60 * 60 * 24 },
})
);
// MongoDB setup for production
// mongoose.connect(process.env.MONGODBONLINE_URL, {
// useNewUrlParser: true,
// useUnifiedTopology: true,
// useCreateIndex: true,
// });
// MongoDB setup for development
mongoose.connect(process.env.MONGODBLOCAL_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
});
// Custom middleware to check if user not login
const checkLogin = (req, res, next) => {
if (!req.session.username) {
res.redirect("/login");
} else {
next();
}
};
// Custom middleware to prevent user from accessing routes that don't need after logged in
const preventWhenLogged = (req, res, next) => {
if (req.session.username) {
res.redirect("/");
} else {
next();
}
};
// Index endpoint
app.get("/", (req, res) => {
if (req.session.username) {
res.render("index", {
username: req.session.username,
});
} else {
res.render("index");
}
});
// User log in endpoint
app.get("/login", preventWhenLogged, (req, res) => {
res.render("login");
});
app.post("/login", preventWhenLogged, (req, res) => {
AccountModel.findOne({
username: req.body.username,
})
.then((data) => {
bcrypt
.compare(req.body.password, data.password)
.then(function (result) {
if (result) {
req.session.username = req.body.username;
res.redirect("/");
} else {
res.render("login", {
error: "Invalid email or password",
});
}
});
})
.catch((err) => {
res.render("login", {
error: "Invalid email or password",
});
});
});
// User sign up endpoint
app.get("/signup", preventWhenLogged, (req, res) => {
res.render("signup");
});
app.post("/signup", preventWhenLogged, (req, res) => {
var username = req.body.username;
var password = req.body.password;
var confirmpassword = req.body.confirmpassword;
let encryptedPassword = "";
if (confirmpassword != password) {
res.render("signup", {
error: "Confirm password does not match",
});
} else {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(password, salt, function (err, hash) {
encryptedPassword = hash;
AccountModel.findOne({
username: username,
})
.then((data) => {
/* const passwordhash = bcrypt.hash(password, 10)
const confirmpasswordhash = bcrypt.hash(confirmpassword, 10) */
if (data) {
res.render("signup", {
error: "User has already existed",
});
} else {
AccountModel.create({
username: username,
password: encryptedPassword,
});
res.redirect("/login");
}
})
.catch((err) => {
res.render("signup", {
error: "User has already existed",
});
});
});
});
}
});
// User logout endpoint
app.get("/logout", checkLogin, (req, res) => {
req.session.destroy((error) => {
if (error) {
res.redirect("/");
} else {
res.clearCookie(SESSION_NAME);
res.redirect("/");
}
});
});
// Join by room id or create room endpoint
app.get("/roomoption", checkLogin, (req, res) => {
res.render("roomOption");
});
// Join room by id endpoint
app.post("/join", checkLogin, (req, res) => {
res.redirect(`/meetingroom/${req.body.joinRoomId}`);
});
// Create room endpoint
app.get("/create", checkLogin, (req, res) => {
res.redirect(`/meetingroom/${v4UniqueId()}`);
});
// Meeting room endpoint
app.get("/meetingroom/:id", checkLogin, (req, res) => {
res.render("meetingRoom", {
meetingRoomId: req.params.id,
username: req.session.username,
});
});
// Server listen to the emitting messages from client to take on action
io.on("connection", (socket) => {
// When server has listened to the emitting message from user,
// it will take the user to the specific room that the user is asking to entry
// and emit all the users of that room to know that the new user has entried
socket.on("Entry room", (meetingRoomId, userId) => {
socket.join(meetingRoomId);
socket
.to(meetingRoomId)
.broadcast.emit("New user has connected", userId);
// Server listen to the emitting message when client input their message
// and emit back a message to allow client rendering new message on the web page
socket.on("New message", (newMessage, username) => {
io.to(meetingRoomId).emit("Add new message", newMessage, username);
});
});
});
// Server listen
httpServer.listen(port, () => {
console.log(`Server is running at port ${port}`);
});