Change password, create account, qr code cookies

This commit is contained in:
2025-02-20 11:12:15 -05:00
parent 05547f650a
commit 0ad4f0d6c2
5 changed files with 92 additions and 42 deletions

View File

@@ -1,6 +1,7 @@
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const cookieParser = require('cookie-parser');
const QRCode=require('qrcode');
const crypto=require('crypto');
const path=require('path');
@@ -14,6 +15,8 @@ const app = express();
app.set('view engine','ejs');
app.use(express.json());
app.use(express.static('public'));
app.use(cookieParser());
const PORT = 3000;
const MainURL ="http://localhost:3000";
const PWSalt ="!SaltyMagic7283715374";
@@ -38,6 +41,9 @@ const QRSalt ="!SaltyMagic5392370662";
// + Turn ticket use on/off from Settings (Admin)
// + Turn email on/off from Settings (Admin)
// + Magic-link Login System
// Setting to deactivate transfers globally
// Mass-import of individual tickets
// Cookie based QR code functionality
// Create Account (User)
// Change Password (User)
// Deactivate individual magic links (User)
@@ -525,53 +531,56 @@ app.get('/logout', (req, res) => {
});
app.get('/signup', (req, res) => {
res.send(`
<h1>Sign Up</h1>
<form method="POST" action="/signup">
<label>Username: <input type="text" name="username" required></label><br>
<label>Password: <input type="password" name="password" required></label><br>
<button type="submit">Sign Up</button>
</form>
<a href="/login">Log In</a>
`);
app.get('/create', (req, res) => {
return res.render("create");
});
app.post('/signup', (req, res) => {
const { username, password } = req.body;
if (users[username]) {
return res.send('User already exists. <a href="/signup">Try again</a>');
}
users[username] = { password: hashPW(password) };
app.post('/create', async (req, res) => {
const { username, password1, password2 } = req.body;
if (password1!=password2) return res.render("error",{ message: "Passwords do not match."} );
if (users[username] && !users[username].needsconfirm) return res.render("error",{ message: "Email (username) already exists."} );
if (users[username] && users[username].needsconfirm) {
await client.sendEmail({ From: "tickets@fallsonfire.net",
To: username,
Subject: "Falls on Fire: Confirm Account Creation",
TextBody: "Click here to confirm creation of account "+username,
HTMLBody: "Click here to confirm creation of account "+username
});
return res.render("message",{ message: "Email has not yet been confirmed. Resent confirm link." });
}
users[username] = { password: hashPW(password1), needsconfirm:false };
console.log("Created new account:",username);
res.redirect('/login');
});
if (users[username].needsconfirm) return res.render("message",{ message: "Check email to confirm account creation." });
return res.render("message",{ message: "Account created. You may now log in." });
});
app.get('/changepassword', (req, res) => {
res.send(`
<h1>Change Password</h1>
<form method="POST" action="/changepassword">
<label>Password: <input type="password" name="password1" required></label><br>
<label>Again: <input type="password" name="password2" required></label><br>
<button type="submit">Sign Up</button>
</form>
<a href="/">Home</a>
`);
});
app.post('/changepassword', (req, res) => {
const { password1, password2 } = req.body;
if (!req.session.username) {
return res.send('You are not logged in<a href="/">Back</a>');
}
if (password1!=password2) {
return res.send('Passwords do not match<a href="/">Back</a>');
}
users[req.session.username].password=hashPW(password1);
res.redirect('/');
app.get("/scanqron", (req,res) => {
res.cookie("fof_scanqr","on",{ maxAge: 7 * 24 * 60 * 60 * 1000 });
return res.redirect("/checkscanqr");
});
app.get("/scanqroff", (req,res) => {
res.cookie("fof_scanqr","off");
return res.redirect("/checkscanqr");
});
app.get("/checkscanqr", (req,res) => {
const scan=req.cookies["fof_scanqr"];
return res.render("message",{ message: "QR Code Scanning is "+(scan=="on" ? "On" : "Off") });
});
app.get('/changepassword', requireLogin,(req, res) => {
return res.render("changepassword");
});
app.post('/changepassword', requireLogin,(req, res) => {
const { password0, password1, password2 } = req.body;
if (users[req.session.username].password!=hashPW(password0)) return res.render("error",{ message: "Old Password is not correct."});
if (password1!=password2) return res.render("error",{ message: "Passwords do not match."})
users[req.session.username].password=hashPW(password1);
return res.render("message",{ message: "Password changed."})
});

20
views/changepassword.ejs Normal file
View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Change Password</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<%- include('partials/nav') %>
<div class="content">
Change Password
<form id="editor" method="POST" action="/changepassword">
Old Password:<input type="password" name="password0"><br>
New Password:<input type="password" name="password1"><br>
Repeat New Password:<input type="password" name="password2"><br>
<button id="Submit" type="submit">Change Password</button>
<br>
</form>
</div>
</body>
</html>

20
views/create.ejs Normal file
View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<%- include('partials/nav') %>
<div class="content">
In most cases you don't need to create an account because this ticketing system works primarily with links sent through email. Gate volunteers are an exception.
<form id="editor" method="POST" action="/create">
Email:<input type="email" name="username"><br>
Password:<input type="password" name="password1"><br>
Repeat Password:<input type="password" name="password2"><br>
<button id="Submit" type="submit">Create Account</button>
<br>
</form>
</div>
</body>
</html>

View File

@@ -8,6 +8,7 @@
<%- include('partials/nav') %>
<div class="content">
An error has occurred.
<%=message%>
</div>
</body>
</html>

View File

@@ -7,8 +7,8 @@
<body>
<%- include('partials/nav') %>
<div class="content">
Message, See above.
<%=message%>
</div>
</body>
</html>