1
0
forked from w0bm/f0bm
Files
f0bm/src/inc/routes/admin.mjs

262 lines
7.8 KiB
JavaScript

import db from "../sql.mjs";
import lib from "../lib.mjs";
import { exec } from "child_process";
import { promises as fs } from "fs";
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$/, lib.loggedin, 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: "<form action=\"/login/pwdgen\" method=\"post\"><input type=\"text\" name=\"pwd\" placeholder=\"pwd\" /><input type=\"submit\" value=\"f0ck it\" /></form>"
});
});
router.post(/^\/login\/pwdgen$/, async (req, res) => {
res.reply({
body: await lib.hash(req.post.pwd)
});
});
router.get(/^\/admin(\/)?$/, lib.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(\/)?$/, lib.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\/approve\/?/, lib.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}`;
// Check if files need moving (if they are in deleted/)
try {
await fs.access(`./public/b/${f0ck[0].dest}`);
// Exists in public, good (new upload)
} catch {
// Not in public, likely a deleted item being recovered
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.writeHead(302, {
"Location": `/${id}`
}).end();
}
const _posts = await db`
select id, mime, username, dest
from "items"
where
active = 'false'
order by id desc
`;
if (_posts.length === 0) {
return res.reply({
body: tpl.render('admin/approve', { posts: [], tmp: null }, req)
});
}
const posts = await Promise.all(_posts.map(async p => {
// Try to get thumbnail from public or deleted
let thumb;
try {
// Try public first
thumb = (await fs.readFile(`./public/t/${p.id}.webp`)).toString('base64');
} catch {
try {
thumb = (await fs.readFile(`./deleted/t/${p.id}.webp`)).toString('base64');
} catch {
thumb = ""; // No thumbnail?
}
}
return {
...p,
thumbnail: thumb
};
}));
res.reply({
body: tpl.render('admin/approve', {
posts,
tmp: null
}, req)
});
});
router.get(/^\/admin\/deny\/?/, lib.auth, async (req, res) => {
console.log('[ADMIN DENY] Logs initiated');
if (req.url.qs?.id) {
const id = +req.url.qs.id;
console.log(`[ADMIN DENY] Denying ID: ${id}`);
try {
const f0ck = await db`
select dest, mime
from "items"
where
id = ${id}
limit 1
`;
if (f0ck.length > 0) {
console.log(`[ADMIN DENY] Found item, deleting files: ${f0ck[0].dest}`);
// Delete files
await fs.unlink(`./public/b/${f0ck[0].dest}`).catch(e => console.log('File error pub/b:', e.message));
await fs.unlink(`./public/t/${id}.webp`).catch(e => console.log('File error pub/t:', e.message));
await fs.unlink(`./deleted/b/${f0ck[0].dest}`).catch(e => console.log('File error del/b:', e.message));
await fs.unlink(`./deleted/t/${id}.webp`).catch(e => console.log('File error del/t:', e.message));
if (f0ck[0].mime.startsWith('audio')) {
await fs.unlink(`./public/ca/${id}.webp`).catch(() => { });
await fs.unlink(`./deleted/ca/${id}.webp`).catch(() => { });
}
// Delete DB entries
console.log('[ADMIN DENY] Deleting DB entries...');
try {
await db`delete from "tags_assign" where item_id = ${id}`;
await db`delete from "favorites" where item_id = ${id}`;
await db`delete from "comments" where item_id = ${id}`.catch(() => { });
await db`delete from "items" where id = ${id}`;
console.log('[ADMIN DENY] Deleted successfully');
} catch (dbErr) {
console.error('[ADMIN DENY DB ERROR]', dbErr);
}
} else {
console.log('[ADMIN DENY] Item not found in DB');
}
} catch (err) {
console.error('[ADMIN DENY ERROR]', err);
}
return res.writeHead(302, {
"Location": `/admin/approve`
}).end();
}
console.log('[ADMIN DENY] No ID provided');
return res.writeHead(302, { "Location": "/admin/approve" }).end();
});
return router;
};