Archived
1
0
Fork 0

Add reCaptcha

This commit is contained in:
Ethanell 2020-08-20 22:46:46 +02:00
parent d98dcb0c07
commit c69dc9a98e
11 changed files with 60 additions and 14 deletions

7
app.js
View file

@ -4,6 +4,8 @@ let cookieParser = require("cookie-parser");
let session = require("express-session"); let session = require("express-session");
let logger = require("morgan"); let logger = require("morgan");
let { I18n } = require("i18n"); let { I18n } = require("i18n");
let Recaptcha = require("express-recaptcha").RecaptchaV3;
let config = process.env.NODE_ENV === "test" ? {} : require("./config/config.json");
let indexRouter = require("./routes/index"); let indexRouter = require("./routes/index");
let registerRouter = require("./routes/register"); let registerRouter = require("./routes/register");
@ -17,7 +19,7 @@ let adminRouter = require("./routes/admin");
let app = express(); let app = express();
let sess = { let sess = {
secret: process.env.NODE_ENV === "test" ? "Keyboard Cat" : require("./config/config.json").secret, secret: process.env.NODE_ENV === "test" ? "Keyboard Cat" : config.secret,
cookie: {} cookie: {}
}; };
let i18n = new I18n({ let i18n = new I18n({
@ -27,6 +29,7 @@ let i18n = new I18n({
directory: __dirname + "/locales", directory: __dirname + "/locales",
objectNotation: true objectNotation: true
}); });
let recaptcha = process.env.NODE_ENV === "test" ? null : new Recaptcha(config.siteKey, config.secretKey, {callback: "cb"});
if (app.get("env") === "production") { if (app.get("env") === "production") {
app.set("trust proxy", 1); app.set("trust proxy", 1);
@ -36,6 +39,7 @@ if (app.get("env") === "production") {
// view engine setup // view engine setup
app.set("views", path.join(__dirname, "views")); app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug"); app.set("view engine", "pug");
app.set("recaptcha", recaptcha);
app.use(logger("dev")); app.use(logger("dev"));
app.use(express.json()); app.use(express.json());
@ -48,6 +52,7 @@ if(process.env.NODE_ENV === "test")
app.locals.test = true; app.locals.test = true;
app.use((req, res, next) => { app.use((req, res, next) => {
res.locals.user = req.session.user; res.locals.user = req.session.user;
res.locals.captcha = process.env.NODE_ENV === "test" ? undefined : recaptcha.render();
next(); next();
}); });

View file

@ -6,5 +6,7 @@
"database": "database_development", "database": "database_development",
"host": "127.0.0.1", "host": "127.0.0.1",
"dialect": "mysql" "dialect": "mysql"
} },
"siteKey": "yjt,kugcjvhkyhgchkuyjgugjgcvkuh",
"secretKey": "yjt,vhjtfykjvhkhiuyhjvkjuiyvhjblhioguikjkly_lui"
} }

13
middlewares/reCaptcha.js Normal file
View file

@ -0,0 +1,13 @@
let error = require("../routes/utils/error");
module.exports = (req, res, next) => {
if(req.app.locals.test)
return next();
req.app.get("recaptcha").middleware.verify(req, res, () => {
if (req.recaptcha.error)
error(req, res, "Strange behaviour detected !", 400,
req.app.get("env") !== "production" ? req.recaptcha.error : undefined);
else
next();
});
};

5
package-lock.json generated
View file

@ -887,6 +887,11 @@
} }
} }
}, },
"express-recaptcha": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/express-recaptcha/-/express-recaptcha-5.0.2.tgz",
"integrity": "sha512-111xDDJo1HPVwcU+hG1X3vOzRFWx/Yp9pyQ7qOVjkSfRXh2qeU9tLo1I0HBa1oLrB8rQlyxLUI9XXP5iUePnnw=="
},
"express-session": { "express-session": {
"version": "1.17.1", "version": "1.17.1",
"resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",

View file

@ -10,6 +10,7 @@
"cookie-parser": "~1.4.4", "cookie-parser": "~1.4.4",
"debug": "~2.6.9", "debug": "~2.6.9",
"express": "~4.16.1", "express": "~4.16.1",
"express-recaptcha": "^5.0.2",
"express-session": "^1.17.1", "express-session": "^1.17.1",
"http-errors": "~1.6.3", "http-errors": "~1.6.3",
"i18n": "^0.12.0", "i18n": "^0.12.0",

View file

@ -1,6 +1,7 @@
const express = require("express"); const express = require("express");
const router = express.Router(); const router = express.Router();
const models = require("../models"); const models = require("../models");
const reCaptcha = require("../middlewares/reCaptcha");
router.get("/", async (req, res) => { router.get("/", async (req, res) => {
if (req.session.user) if (req.session.user)
@ -8,7 +9,7 @@ router.get("/", async (req, res) => {
else else
res.render("login", { title: "SOD - Login" }); res.render("login", { title: "SOD - Login" });
}) })
.post("/", async (req, res) => { .post("/", reCaptcha, async (req, res) => {
if (!req.body.username || !req.body.password) if (!req.body.username || !req.body.password)
res.redirect("/login"); res.redirect("/login");
else { else {

View file

@ -2,15 +2,16 @@ let express = require("express");
let router = express.Router(); let router = express.Router();
let models = require("../models"); let models = require("../models");
let userCreate = require("./utils/userCreate"); let userCreate = require("./utils/userCreate");
let reCaptcha = require("../middlewares/reCaptcha");
router.get("/", async (req, res) => { router.get("/", async (req, res) => {
if (req.session.user) if (req.session.user)
res.redirect("/"); res.redirect("/");
else else
res.render("register", {title: "SOD - register", departments: await models.Department.findAll()}); res.render("register", {title: "SOD - register", departments: await models.Department.findAll()});
}) })
.post("/", async (req, res) => { .post("/", reCaptcha, async (req, res) => {
let user = await userCreate(req, res); let user = await userCreate(req, res);
if (user) { if (user) {
req.session.user = user; req.session.user = user;

View file

@ -1,3 +1,5 @@
include mixin
doctype html doctype html
html html
head head
@ -57,19 +59,19 @@ html
a(href="https://www.linkedin.com/in/florian-charlaix" target="_blank") Florian Charlaix a(href="https://www.linkedin.com/in/florian-charlaix" target="_blank") Florian Charlaix
div#contact.popup.card.hide div#contact.popup.card.hide
h1=__("layout.contact") h1=__("layout.contact")
p.before-link=__("layout.orderIssue")+":" p.before-link=__("layout.orderIssue") + ":"
a(href="mailto: ") test@test.fr a(href="mailto: ") test@test.fr
p.before-link=__("layout.bio")+":" p.before-link=__("layout.bio") + ":"
a(href="mailto: ") a(href="mailto: ")
p.before-link=__("layout.chemistry")+":" p.before-link=__("layout.chemistry") + ":"
a(href="mailto: ") a(href="mailto: ")
p.before-link=__("layout.GC")+":" p.before-link=__("layout.GC") + ":"
a(href="mailto: ") a(href="mailto: ")
p.before-link=__("layout.GCPD")+":" p.before-link=__("layout.GCPD") + ":"
a(href="mailto: bde.gcgp.lyon1@gmail.com") bde.gcgp.lyon1@gmail.com a(href="mailto: bde.gcgp.lyon1@gmail.com") bde.gcgp.lyon1@gmail.com
p.before-link=__("layout.GEA")+":" p.before-link=__("layout.GEA") + ":"
a(href="mailto: ") a(href="mailto: ")
p.before-link=__("layout.IT")+":" p.before-link=__("layout.IT") + ":"
a(href="mailto: contact@bde-info.org") contact@bde-info.org a(href="mailto: contact@bde-info.org") contact@bde-info.org
script(src="/javascripts/layout.js") script(src="/javascripts/layout.js")

View file

@ -10,4 +10,4 @@ block content
label(for="password")=__("password")+":" label(for="password")=__("password")+":"
input#password(type="password" name="password" required) input#password(type="password" name="password" required)
div.field div.field
input(type="submit" value=__("login.submit")) +submit(value=__("login.submit"))

16
views/mixin.pug Normal file
View file

@ -0,0 +1,16 @@
mixin submit(value)
div.recaptcha.recaptcha-cb
input(type="submit" value!=value)
if !test
p !{captcha}
script.
function cb(token) {
document.querySelectorAll("div.recaptcha.recaptcha-cb").forEach(el => {
el.classList.remove("recaptcha-cb");
let input = document.createElement("input");
input.setAttribute("type", "hidden");
input.setAttribute("name", "g-recaptcha-response");
input.setAttribute("value", token);
el.appendChild(input);
});
}

View file

@ -22,7 +22,7 @@ block content
label(for="password")=__("password")+":" label(for="password")=__("password")+":"
input#password(type="password" name="password" required) input#password(type="password" name="password" required)
div.field div.field
input(type="submit" value=__("register.submit")) +submit(value=__("register.submit"))
datalist#department-list datalist#department-list
each department in departments each department in departments