Untitled
unknown
javascript
2 years ago
8.3 kB
7
Indexable
require("dotenv").config() // lets me use dot env to store sensitive data
// importing my librarys
const express = require("express");
const path = require("path");
const jwt = require("jsonwebtoken");
const bcrypt = require('bcrypt');
const cookieParser = require("cookie-parser");
// importing files
const pool = require('./database.js');
const publicDir = path.join(__dirname, "./public");
const viewsDir = path.join(__dirname, "./views");
//setting up web server
const app = express();
app.set("view engine", "hbs");
app.set("views", viewsDir);
app.use(express.static(publicDir));
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(cookieParser())
//routes
app.get("/", (req, res) => {
res.render("index");
});
app.get("/quiz", (req, res) => {
const token = req.cookies.AuthToken;
if (!token) {
// Token is missing
res.sendStatus(401).send("token invalid");
return;
}
jwt.verify(token, process.env.SECRET_ACCESS_TOKEN, (err, decoded) => {
if (err) {
// Token is invalid
res.sendStatus(401).send("token invalid");
} else {
// Check if the user is a parent
if (decoded.isParent) {
// Parent accounts are not allowed to access stats
res.sendStatus(403).send("parents are not allowed here"); // Forbidden
} else {
// User is not a parent, continue with protected logic
// Query to select a random question from the QuestionInfo table
pool.query('SELECT * FROM QuestionInfo ORDER BY RAND() LIMIT 1', (error, results, fields) => {
if (error) {
console.error('Error retrieving random question:', error);
res.status(500).send('Error retrieving random question');
return;
}
// Assuming there's at least one question returned from the query
const randomQuestion = results[0];
let answer1 = randomQuestion.Answers[0]
let answer2 = randomQuestion.Answers[1]
let answer3 = randomQuestion.Answers[2]
let answer4 = randomQuestion.Answers[3]
res.render("quiz", { question: randomQuestion, answer1: answer1, answer2: answer2, answer3: answer3, answer4: answer4 });
});
}
}
});
});
app.get("/stats", (req, res) => {
const token = req.cookies.AuthToken;
if (!token) {
// Token is missing
res.sendStatus(401);
return;
}
jwt.verify(token, process.env.SECRET_ACCESS_TOKEN, (err, decoded) => {
if (err) {
// Token is invalid
res.sendStatus(401);
} else {
// Token is valid, continue with protected logic
res.render("stats");
}
});
});
app.get("/signup", (req, res) => {
res.render("signup");
});
app.get("/login", (req, res) => {
res.render("login");
});
app.post('/signup', async (req, res) => {
let userData = {
UserEmail: req.body.Email,
UserName: req.body.Name,
UserHashedPassword: await HashPassword(req.body.Password),
ParentName: req.body.ParentName,
ParentEmail: req.body.ParentEmail,
ParentHashedPassword: await HashPassword(req.body.ParentPassword),
Course: req.body.Course
};
// Insert the user data into the database
pool.query('INSERT INTO UserInfo SET ?', userData, (error, results, fields) => {
if (error) {
console.error('Error inserting user data:', error);
res.status(500).send('Error inserting user data');
return;
}
console.log('User data inserted successfully');
res.status(200).redirect('/');
});
const user = {
email: req.body.Email,
isParent: false
}
const token = jwt.sign(user, process.env.SECRET_ACCESS_TOKEN, { expiresIn: '1m' });
res.cookie('AuthToken', token, { httpOnly: false, maxAge: 60000 });
});
app.post('/login', (req, res) => {
const isParent = req.body.isParent ? true : false; // Is login sent by a parent?
if (isParent) { // If the login request is sent from a parent
const email = req.body.email;
const enteredPassword = req.body.password;
pool.query('SELECT ParentHashedPassword FROM UserInfo WHERE ParentEmail = ?', [email], async (error, results, fields) => {
if (error) {
console.error('Error querying database:', error);
res.status(500).send('Error querying database');
return;
}
if (results.length === 0) {
// User not found
res.status(401).send('Invalid email or password');
return;
}
const hashedPassword = results[0].ParentHashedPassword;
try {
const isMatch = await ComparePasswords(enteredPassword, hashedPassword);
if (!isMatch) {
// Incorrect password
res.status(401).send('Invalid email or password');
return;
}
// Password is correct, proceed with authentication
const user = {
email: email,
isParent: isParent
};
const token = jwt.sign(user, process.env.SECRET_ACCESS_TOKEN, { expiresIn: '1m' });
res.cookie('AuthToken', token, { httpOnly: false, maxAge: 60000 });
res.redirect('/');
} catch (error) {
console.error('Error comparing passwords:', error);
res.status(500).send('Error comparing passwords');
}
});
} else { // if the login is from a studen account
const email = req.body.email;
const enteredPassword = req.body.password;
pool.query('SELECT UserHashedPassword FROM UserInfo WHERE UserEmail = ?', [email], async (error, results, fields) => {
if (error) {
console.error('Error querying database:', error);
res.status(500).send('Error querying database');
return;
}
if (results.length === 0) {
// User not found
res.status(401).send('Invalid email or password');
return;
}
const hashedPassword = results[0].UserHashedPassword;
try {
const isMatch = await ComparePasswords(enteredPassword, hashedPassword);
if (!isMatch) {
// Incorrect password
res.status(401).send('Invalid email or password');
return;
}
// Password is correct, proceed with authentication
const user = {
email: email,
isParent: isParent
};
const token = jwt.sign(user, process.env.SECRET_ACCESS_TOKEN, { expiresIn: '1m' });
res.cookie('AuthToken', token, { httpOnly: false, maxAge: 60000 });
res.redirect('/');
} catch (error) {
console.error('Error comparing passwords:', error);
res.status(500).send('Error comparing passwords');
}
});
}
});
app.post('/answer', (req, res) => {
const answer = req.body.answer;
const questionId = req.body.questionId;
// Query the database to retrieve the correct answer for the given questionId
pool.query('SELECT CorrectAnswer FROM QuestionInfo WHERE QuestionID = ?', [questionId], (error, results, fields) => {
if (error) {
console.error('Error retrieving correct answer:', error);
return res.status(500).json({ error: 'Internal server error' });
}
console.log(results)
// Assuming there's exactly one result (since QuestionID is unique)
if (results.length !== 1) {
return res.status(400).json({ error: 'Question not found' });
}
const correctAnswer = results[0].CorrectAnswer;
// Check if the submitted answer is correct
const isCorrect = (answer === correctAnswer);
res.json({ isCorrect });
});
});
async function HashPassword(password) {
const salt = await bcrypt.genSalt();
const HashedPassword = await bcrypt.hash(password, salt)
return HashedPassword
}
async function ComparePasswords(EnteredPassword, HashedPassword) {
return bcrypt.compare(EnteredPassword, HashedPassword)
.then((result) => {
return result;
})
.catch((error) => {
console.error('Error comparing passwords:', error);
throw error;
});
}
app.listen(3000, () => {
console.log("server started on port 3000");
});Editor is loading...
Leave a Comment