Skip to content

Commit

Permalink
feat: worked on csrf token for most server requests
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbrusegard committed Oct 5, 2023
1 parent 8f4932b commit 13df75f
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 59 deletions.
135 changes: 135 additions & 0 deletions admin/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"@google-cloud/storage": "^7.1.0",
"axios": "^1.4.0",
"bcrypt": "^5.1.1",
"crypto": "^1.0.1",
"dotenv": "^16.3.1",
"ejs": "^3.1.9",
"express": "^4.18.2",
"express-rate-limit": "^7.0.2",
"express-session": "^1.17.3",
Expand Down
52 changes: 21 additions & 31 deletions admin/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const express = require("express");
const rateLimit = require("express-rate-limit");
const sessions = require("express-session");
const bcrypt = require("bcrypt");
const crypto = require("crypto");

const multer = require("multer");
const upload = multer({ storage: multer.memoryStorage() });
Expand All @@ -20,27 +21,28 @@ bcrypt.hash(process.env.ADMIN_PASSWORD, 10, (err, hash) => {

const app = express();

app.set("view engine", "ejs");
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
sessions({
secret: process.env.SESSION_SECRET,
saveUninitialized: true,
cookie: {
maxAge: 60 * 1000 * 15,
secure: process.env.SERVE_ONLY_HTTPS === "true",
sameSite: "strict",
httpOnly: true,
},
resave: false,
})
);

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

let session;
const loginHtml = `
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="viewport" content="width=device-width, initial-scale=10" />
<title>Admin | Niclas Nordlund Photography</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
Expand All @@ -64,6 +66,7 @@ const loginHtml = `
</head>
<body>
<form method="POST">
<input type="hidden" id="csrfToken" name="csrfToken" value="" />
<label for="password">Password:</label>
<input type="password" id="password" name="password" />
<button type="submit">Submit</button>
Expand All @@ -75,7 +78,7 @@ const loginHtml = `

const limiter = rateLimit({
windowMs: 60 * 1000 * 15, // 15 minutes
max: 5, // 5 failed attempts allowed in that window
max: 10, // 10 failed attempts allowed in that window
message: loginHtml.replace(
"<p></p>",
"<p>Too many login attempts, try again in 15 minutes.</p>"
Expand All @@ -84,8 +87,12 @@ const limiter = rateLimit({

app.get("/", limiter, (req, res) => {
if (req.session && req.session.userid) {
res.sendFile(path.join(__dirname, "index.html"));
} else res.send(loginHtml);
const token = crypto.randomBytes(64).toString("hex");
req.session.csrfToken = token;
res.render("index", { csrfToken: token });
} else {
res.send(loginHtml);
}
});

app.post("/", limiter, (req, res) => {
Expand All @@ -110,31 +117,14 @@ app.post("/", limiter, (req, res) => {
}
);
});
app.post("/", limiter, (req, res) => {
bcrypt.compare(
req.body.password,
process.env.ADMIN_PASSWORD,
(err, result) => {
if (err) {
console.error("Error comparing passwords:", err);
res.status(500).send("Internal Server Error");
} else if (result) {
req.session.userid = "admin";
res.redirect("/");
} else {
res.send(
loginHtml.replace(
"<p></p>",
"<p>Incorrect password. Please try again.</p>"
)
);
}
}
);
});

function authenticate(req, res, next) {
if (req.session && req.session.userid) {
if (
req.session &&
req.session.userid &&
req.session.csrfToken === req.headers["csrf-token"]
) {
console.log("Authenticated");
next();
} else {
res.status(401).send("Unauthorized");
Expand Down
Loading

0 comments on commit 13df75f

Please sign in to comment.