Setup SMTP client and email check
This commit is contained in:
parent
0ae014549d
commit
f47a72acda
10 changed files with 735 additions and 651 deletions
1
app.js
1
app.js
|
@ -40,6 +40,7 @@ app.use((req, res, next) => {
|
||||||
|
|
||||||
app.use("/", indexRouter);
|
app.use("/", indexRouter);
|
||||||
app.use("/login", loginRouter);
|
app.use("/login", loginRouter);
|
||||||
|
app.use("/email", require("./routes/email"));
|
||||||
|
|
||||||
// catch 404 and forward to error handler
|
// catch 404 and forward to error handler
|
||||||
app.use((req, res) => {
|
app.use((req, res) => {
|
||||||
|
|
4
bin/www
4
bin/www
|
@ -8,6 +8,8 @@ const app = require("../app");
|
||||||
const debug = require("debug")("letu:server");
|
const debug = require("debug")("letu:server");
|
||||||
const http = require("http");
|
const http = require("http");
|
||||||
const models = require("../models");
|
const models = require("../models");
|
||||||
|
const { SMTPClient } = require("emailjs");
|
||||||
|
const mailClient = new SMTPClient(process.env.NODE_ENV === "test" ? {} : require("../config/config.json").email.server);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get port from environment and store in Express.
|
* Get port from environment and store in Express.
|
||||||
|
@ -15,6 +17,7 @@ const models = require("../models");
|
||||||
|
|
||||||
let port = normalizePort(process.env.PORT || "3000");
|
let port = normalizePort(process.env.PORT || "3000");
|
||||||
app.set("port", port);
|
app.set("port", port);
|
||||||
|
app.set("mailClient", mailClient);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create HTTP server.
|
* Create HTTP server.
|
||||||
|
@ -28,6 +31,7 @@ let server = http.createServer(app);
|
||||||
|
|
||||||
const io = require("socket.io")(server);
|
const io = require("socket.io")(server);
|
||||||
io.use((socket, next) => app.get("sessionMiddleware")(socket.request, socket.request.res || {}, next));
|
io.use((socket, next) => app.get("sessionMiddleware")(socket.request, socket.request.res || {}, next));
|
||||||
|
io.mailClient = mailClient;
|
||||||
io.on("connection", require("../sockets"));
|
io.on("connection", require("../sockets"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,6 +7,17 @@
|
||||||
"dialect": "postgres",
|
"dialect": "postgres",
|
||||||
"operatorsAliases": false
|
"operatorsAliases": false
|
||||||
},
|
},
|
||||||
|
"email": {
|
||||||
|
"server": {
|
||||||
|
"user": "user",
|
||||||
|
"password": "password",
|
||||||
|
"host": "smtp.your-email.com",
|
||||||
|
"ssl": true
|
||||||
|
},
|
||||||
|
"from": "Contact Email <you@email.fr>",
|
||||||
|
"contact": "Your Contact <contact@your-email.fr>",
|
||||||
|
"mailPath": "https://yourServer.com"
|
||||||
|
},
|
||||||
"secret": "keyboard cat",
|
"secret": "keyboard cat",
|
||||||
"passwordPrivateKey": "ecc635295f200847b79299df48e15759"
|
"passwordPrivateKey": "ecc635295f200847b79299df48e15759"
|
||||||
}
|
}
|
||||||
|
|
1255
package-lock.json
generated
1255
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie-parser": "~1.4.4",
|
"cookie-parser": "~1.4.4",
|
||||||
"debug": "~2.6.9",
|
"debug": "~2.6.9",
|
||||||
|
"emailjs": "^3.3.0",
|
||||||
"express": "~4.16.1",
|
"express": "~4.16.1",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
"http-errors": "~1.6.3",
|
"http-errors": "~1.6.3",
|
||||||
|
|
23
routes/email.js
Normal file
23
routes/email.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
const express = require("express");
|
||||||
|
const router = express.Router();
|
||||||
|
const models = require("../models");
|
||||||
|
const error = require("./utils/error");
|
||||||
|
|
||||||
|
router.get("/check", async (req, res) => {
|
||||||
|
if (!req.query.token)
|
||||||
|
return error(req, res, "Missing argument", 400);
|
||||||
|
let user = await models.User.findOne({where: {"emailToken": req.query.token}});
|
||||||
|
if (user) {
|
||||||
|
user.emailVerified = true;
|
||||||
|
if (user.email.endsWith("@etu.univ-lyon1.fr"))
|
||||||
|
user.permissions = 1;
|
||||||
|
else if (user.email.endsWith("@univ-lyon1.fr"))
|
||||||
|
user.permissions = 2;
|
||||||
|
await user.save();
|
||||||
|
res.redirect("/");
|
||||||
|
} else
|
||||||
|
return error(req, res, "Invalid token", 4000);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = router;
|
14
sockets/email/checkResend.js
Normal file
14
sockets/email/checkResend.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
const modules = require("../../models");
|
||||||
|
const emailCheck = require("../utils/emailCheck");
|
||||||
|
|
||||||
|
module.exports = socket => {
|
||||||
|
return async (data) => {
|
||||||
|
let user = await modules.User.findByPk(data.email);
|
||||||
|
if (!user)
|
||||||
|
socket.emit("checkResend", {error: {message: "not_found"}});
|
||||||
|
else if (user.emailVerified)
|
||||||
|
socket.emit("checkResend", {error: {message: "verified_email"}});
|
||||||
|
else
|
||||||
|
await emailCheck(socket, user, null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,18 +3,16 @@ const modules = require("../models");
|
||||||
module.exports = socket => {
|
module.exports = socket => {
|
||||||
return async (data) => {
|
return async (data) => {
|
||||||
let user = await modules.User.findByPk(data.email);
|
let user = await modules.User.findByPk(data.email);
|
||||||
if (!user) {
|
if (!user)
|
||||||
socket.emit("login", null);
|
socket.emit("login", {error: {message: "not_found"}});
|
||||||
return;
|
else if (!user.checkPassword(data.password))
|
||||||
|
socket.emit("login", {error: {message: "invalid_password"}});
|
||||||
|
else if (!user.emailVerified)
|
||||||
|
socket.emit("login", {error: {message: "email_not_verified"}});
|
||||||
|
else {
|
||||||
|
socket.request.session.user = user;
|
||||||
|
socket.request.session.save();
|
||||||
|
socket.emit("login", user)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.checkPassword(data.password)) {
|
|
||||||
socket.emit("login", null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.request.session.user = user;
|
|
||||||
socket.request.session.save();
|
|
||||||
socket.emit("login", user)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
const modules = require("../models");
|
const modules = require("../models");
|
||||||
|
const emailCheck = require("./utils/emailCheck");
|
||||||
|
|
||||||
module.exports = socket => {
|
module.exports = socket => {
|
||||||
return async (data) => {
|
return async (data) => {
|
||||||
if (await modules.User.findByPk(data.email) || !data.email.endsWith("univ-lyon1.fr")) {
|
if (await modules.User.findByPk(data.email))
|
||||||
socket.emit("register", null);
|
socket.emit("register", {error: {message: "email_used"}});
|
||||||
return;
|
else if ((!data.email.endsWith("@univ-lyon1.fr")) && (!data.email.endsWith("@etu.univ-lyon1.fr")))
|
||||||
|
socket.emit("register", {error: {message: "invalid_email"}});
|
||||||
|
else {
|
||||||
|
let user = await modules.User.create({
|
||||||
|
email: data.email,
|
||||||
|
firstName: data.firstName,
|
||||||
|
lastName: data.lastName,
|
||||||
|
passwordHash: data.password
|
||||||
|
});
|
||||||
|
|
||||||
|
await emailCheck(socket, user, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
let user = await modules.User.create({
|
|
||||||
email: data.email,
|
|
||||||
firstName: data.firstName,
|
|
||||||
lastName: data.lastName,
|
|
||||||
passwordHash: data.password
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.request.session.user = user;
|
|
||||||
socket.request.session.save();
|
|
||||||
socket.emit("register", user);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
27
sockets/utils/emailCheck.js
Normal file
27
sockets/utils/emailCheck.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
let crypto = require("crypto");
|
||||||
|
let models = require("../../models");
|
||||||
|
let Message = require("emailjs").Message;
|
||||||
|
const config = require("../../config/config.json");
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = async (socket, user, callBack) => {
|
||||||
|
let token = crypto.randomBytes(16).toString("hex");
|
||||||
|
|
||||||
|
while (await models.User.findOne({where: {emailToken: token}}))
|
||||||
|
token = crypto.randomBytes(16).toString("hex");
|
||||||
|
user.emailToken = token;
|
||||||
|
await user.save();
|
||||||
|
|
||||||
|
socket.server.mailClient.send( new Message({
|
||||||
|
text: `${config.email.mailPath}/email/check?token=${token}`,
|
||||||
|
from: config.email.from,
|
||||||
|
to: user.email,
|
||||||
|
subject: "Email check"
|
||||||
|
}), (err, message) => {
|
||||||
|
if (err)
|
||||||
|
socket.emit("register", null);
|
||||||
|
else
|
||||||
|
if (callBack)
|
||||||
|
callBack();
|
||||||
|
});
|
||||||
|
};
|
Reference in a new issue