ForumExperiment/index.js
2023-04-13 15:21:17 -04:00

155 lines
5.2 KiB
JavaScript

import bcrypt from "bcrypt";
import sqlite3 from "sqlite3";
import { open } from "sqlite";
import express from 'express';
import session from "express-session";
import sfs from "session-file-store";
let FileStore = sfs(session);
const app = express();
const PORT = 3333;
const SALT_COUNT = 12;
const dbPromise = open({
filename: "data.db",
driver: sqlite3.Database,
});
var fileStoreOptions = {};
app.set('view engine', 'ejs');
app.use(
express.urlencoded({ extended: true }),
express.static('static'),
session({
store: new FileStore(fileStoreOptions),
secret: "process.env.SESSION_SECRET", cookie: { maxAge: 60000 },
resave: true,
saveUninitialized: true
}),
);
app.get('/thread/:threadId/', async (req, res) => {
try {
const db = await dbPromise;
const threadId = req.params.threadId;
const thread = await db.get('SELECT * FROM Thread WHERE Thread.id=?', threadId);
if (!thread) throw "";
const messages = await db.all('SELECT Message.*, User.creationdate as accountCreated, User.username FROM Message LEFT JOIN User WHERE Message.author=User.id AND Message.thread=?', threadId);
res.render('pages/thread', { threadinfo: thread, messages: messages, session: req.session });
} catch {
res.redirect('back');
}
});
app.get('/', async (req, res) => {
const db = await dbPromise;
const threads = await db.all('SELECT * FROM Thread');
res.render('pages/index', {
threads: threads,
session: req.session,
});
});
app.get("/login", async (req, res) => {
if (req.session.logged_in) {
return res.redirect('/');
}
res.render('pages/login');
});
app.get("/logout", async (req, res) => {
req.session.logged_in = false;
req.session.user_id = null;
res.redirect("/");
});
app.post("/login", async (req, res) => {
try {
const db = await dbPromise;
const { username, password } = req.body;
if (!username || !password) { return res.render('pages/login', { error: "Username or password not provided" }); }
const user = await db.get(`SELECT password,id FROM User WHERE username = ?`, username);
if (!user) return res.render('pages/login', { error: "Incorrect username or password" });
const compared = await bcrypt.compare(password, user.password);
if (compared) {
req.session.logged_in = true;
req.session.user_id = user.id;
res.redirect("/");
} else {
return res.render('pages/login', { error: "Incorrect username or password" });
}
} catch (err) {
console.log(err);
return res.render('pages/login', { error: "An error ocurred." });
}
});
app.post("/register", async (req, res) => {
try {
const db = await dbPromise;
const { username, password } = req.body;
if (!username || !password) { return res.render('pages/login', { error: "Username or password not provided" }); }
if (username.length < 4) { return res.render('pages/login', { error: "Username must be at least 4 characters long" }); }
if (password.length < 6) { return res.render('pages/login', { error: "Password must be at least 6 characters long" }); }
const passwordHash = await bcrypt.hash(password, SALT_COUNT);
const result = await db.run('INSERT INTO User (username,password,creationdate) VALUES (?,?,unixepoch())', username, passwordHash);
const userID = result.lastID;
req.session.user_id = userID;
req.session.logged_in = true;
res.redirect("/");
} catch (err) {
console.log(err);
if (err.errno) {
switch (err.errno) {
case 19:
return res.render('pages/login', { error: "Username already exists" });
break;
}
}
return res.render('pages/login', { error: "An error ocurred." });
}
});
app.post("/message/:threadId/", async (req, res) => {
try {
const threadId = req.params.threadId;
const db = await dbPromise;
const thread = await db.get('SELECT * FROM Thread WHERE Thread.id=?', threadId);
const messageText = req.body.messageText;
const subjectText = req.body.subjectText;
const userID = req.session.user_id;
await db.run("INSERT INTO Message (text,author,subject,creationdate,thread) VALUES (?,?,?,unixepoch(),?);", messageText, userID, subjectText, threadId);
} catch (err) {
console.error(err);
}
res.redirect('back');
});
app.post("/newthread", async (req, res) => {
try {
const db = await dbPromise;
const threadName = req.body.threadName;
const threadDesc = req.body.threadDesc;
const userID = req.session.user_id;
await db.run("INSERT INTO Thread (name,author,description,creationdate) VALUES (?,?,?,unixepoch());", threadName, userID, threadDesc);
} catch (err) {
console.error(err);
}
res.redirect("/");
});
const setup = async () => {
const db = await dbPromise;
await db.migrate();
app.listen(PORT, () => {
console.log("listening on http://localhost:" + PORT);
});
};
setup();