Add reCaptcha
This commit is contained in:
parent
d98dcb0c07
commit
c69dc9a98e
11 changed files with 60 additions and 14 deletions
7
app.js
7
app.js
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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
13
middlewares/reCaptcha.js
Normal 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
5
package-lock.json
generated
|
@ -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",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
16
views/mixin.pug
Normal 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);
|
||||||
|
});
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
Reference in a new issue