import { Router } from "express"; import { apiStat } from "../lib.js"; import { hash, compare } from "bcrypt"; import { initDb } from "../db.js"; import { randomBytes } from 'node:crypto'; import { rename } from 'node:fs/promises'; let db = await initDb(); const router = Router(); const minChar = 1; const maxChar = 32; function legalName(user) { return user.search(/[^A-Za-z0-9\-\_]/g) == -1; } router.post('/settings', async (req, res, next) => { let {file} = req; let {username, valid} = res.auth; if (!valid) return; if (file) { await rename(file.path,`./uploads/pfp_${username}.png`); } next(); }); router.post('/logout', (req, res, next) => { res.clearCookie('token'); apiStat(res, next, `Goodbye!`, '/'); return; }); async function login(req, res, next) { let { user, pass } = req.body; if (!pass || !user) { apiStat(res, next, 'Fields are missing.') return; } let isExist = await db.all('SELECT * FROM auth WHERE UPPER(username) LIKE UPPER(?)', [ user ]); // TODO: dont use all if (isExist.length < 1) { apiStat(res, next, `Username wasn't taken.`) return; } let passHash = await compare(pass, isExist[0].password); if (!passHash) { apiStat(res, next, `Password is wrong.`); return; } let token = randomBytes(32).toString('hex'); await db.run('INSERT INTO token (username, token) VALUES (?, ?)', [ user, token ]) res.cookie('token', token); let stat = `Login succeeded.`; apiStat(res, next, stat, '/'); return stat; } router.post('/login', login) router.post('/new', async (req, res, next) => { let { user, pass, pass2 } = req.body; if (pass != pass2) { apiStat(res, next, "Passwords don't match.") return; } if (!pass || !user || !pass2) { apiStat(res, next, 'Fields are missing.') return; } if (!legalName(user)) { apiStat(res, next, 'Username is invalid.') return; } if (user.length < minChar || user.length > maxChar) { apiStat(res, next, `Username length isn't ${minChar} to ${maxChar} characters.`) return; } // TODO: fix this horrible logic chain thing let isExist = await db.all('SELECT * FROM auth WHERE UPPER(username) LIKE UPPER(?)', [ user ]); // TODO: dont use all if (isExist.length > 0) { apiStat(res, next, `Username was taken.`) return; } var passHash = await hash(pass, 10); await db.run('INSERT INTO auth (username, password) VALUES (?, ?)', [ user, passHash ]); let testLogin = await login(req, res, () => { }); apiStat(res, next, `Account created. Login status: ${testLogin}`, '/') }) export default router;