forked from f0ck/f0ckv2
205 lines
5.4 KiB
JavaScript
205 lines
5.4 KiB
JavaScript
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: "<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(\/)?$/, 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. <a href="/admin/recover">back</a>`
|
|
});
|
|
}
|
|
|
|
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;
|
|
};
|