import db from "../sql.mjs"; import lib from "../lib.mjs"; import { exec } from "child_process"; import { promises as fs } from "fs"; const auth = async (req, res, next) => { if(!req.session) { return res.reply({ code: 401, body: "401 - Unauthorized" }); } return next(); }; export default (router, tpl) => { router.get(/^\/login(\/)?$/, async (req, res) => { if(req.cookies.session) { return res.reply({ body: tpl.render('error', { message: "you're already logged in lol", tmp: null }, req) }); } res.reply({ body: tpl.render("login", { theme: req.cookies.theme ?? "f0ck" }) }); }); router.post(/^\/login(\/)?$/, async (req, res) => { const user = await db` select * from "user" where "login" = ${req.post.username.toLowerCase()} limit 1 `; if(user.length === 0) return res.reply({ body: "user doesn't exist or wrong password" }); if(!(await lib.verify(req.post.password, user[0].password))) return res.reply({ body: "user doesn't exist or wrong password" }); const stamp = ~~(Date.now() / 1e3); await db` delete from user_sessions where last_action <= ${(Date.now() - 6048e5)} and kmsi = 0 `; const session = lib.md5(lib.createID()); const blah = { user_id: user[0].id, session: lib.md5(session), browser: req.headers["user-agent"], created_at: stamp, last_used: stamp, last_action: "/login", kmsi: typeof req.post.kmsi !== 'undefined' ? 1 : 0 }; await db` insert into "user_sessions" ${ db(blah, 'user_id', 'session', 'browser', 'created_at', 'last_used', 'last_action', 'kmsi') } `; return res.writeHead(301, { "Cache-Control": "no-cache, public", "Set-Cookie": `session=${session}; Path=/; Expires=Fri, 31 Dec 9999 23:59:59 GMT`, "Location": "/" }).end(); }); router.get(/^\/logout$/, auth, async (req, res) => { const usersession = await db` select * from "user_sessions" where id = ${+req.session.sess_id} `; if(usersession.length === 0) return res.reply({ body: "nope 2" }); await db` delete from "user_sessions" where id = ${+req.session.sess_id} `; return res.writeHead(301, { "Cache-Control": "no-cache, public", "Set-Cookie": "session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT", "Location": "/" }).end(); }); router.get(/^\/login\/pwdgen$/, async (req, res) => { res.reply({ body: "
" }); }); router.post(/^\/login\/pwdgen$/, async (req, res) => { res.reply({ body: await lib.hash(req.post.pwd) }); }); router.get(/^\/admin(\/)?$/, auth, async (req, res) => { // frontpage res.reply({ body: tpl.render("admin", { totals: await lib.countf0cks(), session: req.session, tmp: null }, req) }); }); router.get(/^\/admin\/sessions(\/)?$/, auth, async (req, res) => { const rows = await db` select "user_sessions".*, "user".user from "user_sessions" left join "user" on "user".id = "user_sessions".user_id order by "user_sessions".last_used desc `; res.reply({ body: tpl.render("admin/sessions", { session: req.session, sessions: rows, totals: await lib.countf0cks(), tmp: null }, req) }); }); router.get(/^\/admin\/log(\/)?$/, auth, async (req, res) => { exec("journalctl -qeu f0ck --no-pager", (err, stdout) => { res.reply({ body: tpl.render("admin/log", { log: stdout.split("\n").slice(0, -1), tmp: null }, req) }); }); }); router.get(/^\/admin\/recover\/?/, auth, async (req, res) => { if(req.url.qs?.id) { const id = +req.url.qs.id; const f0ck = await db` select dest, mime from "items" where id = ${id} and active = 'false' limit 1 `; if(f0ck.length === 0) { return res.reply({ body: `f0ck ${id}: f0ck not found` }); } await db`update "items" set active = 'true' where id = ${id}`; await fs.copyFile(`./deleted/b/${f0ck[0].dest}`, `./public/b/${f0ck[0].dest}`).catch(_=>{}); await fs.copyFile(`./deleted/t/${id}.webp`, `./public/t/${id}.webp`).catch(_=>{}); await fs.unlink(`./deleted/b/${f0ck[0].dest}`).catch(_=>{}); await fs.unlink(`./deleted/t/${id}.webp`).catch(_=>{}); if(f0ck[0].mime.startsWith('audio')) { await fs.copyFile(`./deleted/ca/${id}.webp`, `./public/ca/${id}.webp`).catch(_=>{}); await fs.unlink(`./deleted/ca/${id}.webp`).catch(_=>{}); } return res.reply({ body: `f0ck ${id} recovered. back` }); } const _posts = await db` select id, mime, username from "items" where active = 'false' `; if(_posts.length === 0) { return res.reply({ body: 'blah' }); } const posts = await Promise.all(_posts.map(async p => ({ ...p, thumbnail: (await fs.readFile(`./deleted/t/${p.id}.webp`)).toString('base64') }))); res.reply({ body: tpl.render('admin/recover', { posts, tmp: null }, req) }); }); return router; };