sirx: und weg damit :D

This commit is contained in:
Flummi
2021-05-25 14:44:35 +02:00
parent 83fbc557e8
commit f3e357d8a4
17 changed files with 577 additions and 54 deletions

11
src/inc/meddlware.mjs Normal file
View File

@ -0,0 +1,11 @@
export const auth = (req, res) => {
if(!req.session) {
return {
success: false,
redirect: "/"
};
}
return {
success: true
};
};

View File

@ -7,8 +7,21 @@ export default new class Router {
this.routes = new Map();
};
route(method, args) {
this.routes.set(args[0], { method: method, f: args[1] });
console.info("route set", method, args[0]);
// args[0]: route
// args[1]: func || meddlware
const route = args[0];
let func;
let meddlware = null;
if(args.length === 2) {
func = args[1];
}
else {
meddlware = args[1];
func = args[2];
}
this.routes.set(route, { method: method, meddlware: meddlware, f: func });
console.info("route set", method, route);
};
get() {
this.route("GET", arguments);
@ -81,5 +94,5 @@ export default new class Router {
};
Map.prototype.getRoute = function(path, method, tmp) {
return (!(tmp = [...this.entries()].filter(r => ( r[0] === path || r[0].exec?.(path) ) && r[1].method.includes(method) )[0])) ? false : tmp[1].f;
return (!(tmp = [...this.entries()].filter(r => ( r[0] === path || r[0].exec?.(path) ) && r[1].method.includes(method) )[0])) ? false : tmp[1];
};

View File

@ -4,7 +4,8 @@ import tpl from "../tpl.mjs";
import lib from "../lib.mjs";
import util from "util";
import crypto from "crypto";
import cfg from "../../../config.json";
import { auth } from "../meddlware.mjs";
import search from "./inc/search.mjs";
const scrypt = util.promisify(crypto.scrypt);
@ -50,15 +51,12 @@ router.post(/^\/login(\/)?$/, async (req, res) => {
return res.writeHead(301, {
"Cache-Control": "no-cache, public",
"Set-Cookie": `session=${session}; Path=/`,
"Set-Cookie": `session=${session}; Path=/; Expires=Fri, 31 Dec 9999 23:59:59 GMT`,
"Location": "/"
}).end();
});
router.get(/^\/logout$/, async (req, res) => {
if(!req.session)
return res.redirect("/");
router.get(/^\/logout$/, auth, async (req, res) => {
const usersession = await sql("user_sessions").where("id", req.session.sess_id);
if(usersession.length === 0)
return res.reply({ body: "nope 2" });
@ -66,7 +64,7 @@ router.get(/^\/logout$/, async (req, res) => {
await sql("user_sessions").where("id", req.session.sess_id).del();
return res.writeHead(301, {
"Cache-Control": "no-cache, public",
"Set-Cookie": "session=; Path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT",
"Set-Cookie": "session=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT",
"Location": "/login"
}).end();
});
@ -88,11 +86,42 @@ router.get(/^\/login\/test$/, async (req, res) => {
});
});
router.get(/^\/admin(\/)?$/, async (req, res) => {
if(!req.session)
return res.redirect("/");
router.get(/^\/admin(\/)?$/, auth, async (req, res) => { // frontpage
res.reply({
body: tpl.render("views/admin", {}, req)
});
});
router.get(/^\/admin\/sessions(\/)?$/, auth, async (req, res) => {
const rows = await sql("user_sessions")
.leftJoin("user", "user.id", "user_sessions.user_id")
.select("user_sessions.*", "user.user")
.orderBy("user.id");
res.reply({
body: tpl.render("views/admin_sessions", {
sessions: rows
}, req)
});
});
router.get(/^\/admin\/test(\/)?$/, auth, async (req, res) => {
let ret;
if(Object.keys(req.url.qs).length > 0) {
const tag = req.url.qs.tag;
const rows = await sql("tags")
.select("items.id", "items.username", "tags.tag")
.leftJoin("tags_assign", "tags_assign.tag_id", "tags.id")
.leftJoin("items", "items.id", "tags_assign.item_id")
.where("tags.tag", "regexp", tag);
ret = search(rows, tag);
}
res.reply({
body: tpl.render("views/admin_search", {
result: ret
}, req)
});
});

View File

@ -1,5 +1,7 @@
import router from "../router.mjs";
import sql from "../sql.mjs";
import { auth } from "../meddlware.mjs";
import util from "util";
const allowedMimes = [ "audio", "image", "video", "%" ];
@ -71,3 +73,132 @@ router.get(/^\/api\/v2\/user\/.*(\/\d+)?$/, async (req, res) => { // auf qs umst
body: JSON.stringify(rows.length > 0 ? rows : [])
});
});
// adminzeugs
router.post(/^\/api\/v2\/admin\/tags\/add$/, auth, async (req, res) => {
if(!req.post.postid || !req.post.tag) {
return res.reply({ body: JSON.stringify({
success: false,
msg: "missing postid or tag"
})});
}
const postid = +req.post.postid;
const tag = req.post.tag;
if(tag.length >= 45) {
return res.reply({ body: JSON.stringify({
success: false,
msg: "tag is too long!"
})});
}
try {
let tagid;
const tag_exists = await sql("tags").select("id", "tag").where("tag", tag);
if(tag_exists.length === 0) { // create new tag
tagid = (await sql("tags").insert({
tag: tag
}))[0];
}
else {
tagid = tag_exists[0].id;
}
await sql("tags_assign").insert({
tag_id: tagid,
item_id: postid,
prefix: `${req.session.user}@webinterface`
});
} catch(err) {
return res.reply({ body: JSON.stringify({
success: false,
msg: err.message,
tags: await getTags(postid)
})});
}
return res.reply({ body: JSON.stringify({
success: true,
postid: req.post.postid,
tag: req.post.tag,
tags: await getTags(postid)
})});
});
const getTags = async itemid => await sql("tags_assign")
.leftJoin("tags", "tags.id", "tags_assign.tag_id")
.where("tags_assign.item_id", itemid)
.select("tags.id", "tags.tag", "tags_assign.prefix");
const cleanTags = async () => {
const tags = await sql("tags").leftJoin("tags_assign", "tags_assign.tag_id", "tags.id").whereNull("tags_assign.item_id");
if(tags.length === 0)
return;
let deleteTag = sql("tags");
tags.forEach(tag => {
if(["sfw", "nsfw"].includes(tag.tag.toLowerCase()))
return;
deleteTag = deleteTag.orWhere("id", tag.id);
});
await deleteTag.del();
};
router.post(/^\/api\/v2\/admin\/tags\/delete$/, auth, async (req, res) => {
if(!req.post.postid || !req.post.tag) {
return res.reply({ body: JSON.stringify({
success: false,
msg: "missing postid or tag"
})});
}
const postid = +req.post.postid;
const tag = req.post.tag;
const tags = await getTags(postid);
const tagid = tags.filter(t => t.tag === tag)[0]?.id ?? null;
if(!tagid || tagid?.length === 0) {
return res.reply({ body: JSON.stringify({
success: false,
tag: tag,
msg: "tag is not assigned",
tags: await getTags(postid)
})});
}
let q = sql("tags_assign").where("tag_id", tagid).andWhere("item_id", postid).del();
if(req.session.level < 50)
q = q.andWhere("prefix", `${req.session.user}@webinterface`);
const reply = !!(await q);
await cleanTags();
return res.reply({ body: JSON.stringify({
success: reply,
tag: tag,
tagid: tagid,
tags: await getTags(postid)
})});
});
router.get(/^\/api\/v2\/admin\/tags\/get\/\d+$/, auth, async (req, res) => {
return res.reply({ body: JSON.stringify({
tags: await getTags(+req.url.split[5])
})});
});
router.get(/^\/api\/v2\/admin\/deletepost\/\d+$/, auth, async (req, res) => {
if(!req.url.split[4]) {
return res.reply({ body: JSON.stringify({
success: true,
msg: "no postid"
})});
}
const postid = +req.url.split[4];
const rows = await sql("items").where("id", postid).del();
res.reply({ body: JSON.stringify({
success: true
})});
});

View File

@ -0,0 +1,35 @@
export default (obj, word) => {
if(typeof obj !== "object")
return false;
return obj.map(tmp => {
let rscore = 0
, startat = 0
, string = tmp.tag
, cscore
, score;
for(let i = 0; i < word.length; i++) {
const idxOf = string.toLowerCase().indexOf(word.toLowerCase()[i], startat);
if(-1 === idxOf)
return 0;
if(startat === idxOf)
cscore = 0.7;
else {
cscore = 0.1;
if(string[idxOf - 1] === ' ')
cscore += 0.8;
}
if(string[idxOf] === word[i])
cscore += 0.1;
rscore += cscore;
startat = idxOf + 1;
}
score = 0.5 * (rscore / string.length + rscore / word.length);
if(word.toLowerCase()[0] === string.toLowerCase()[0] && score < 0.85)
score += 0.15;
return {
...tmp,
score: score
};
}).sort((a, b) => b.score - a.score);
};

View File

@ -17,17 +17,24 @@ import router from "./inc/router.mjs";
req.url = url.parse(req.url.replace(/(?!^.)(\/+)?$/, ''));
req.url.split = req.url.pathname.split("/").slice(1);
req.url.qs = querystring.parse(req.url.query);
req.url.qs = {...querystring.parse(req.url.query)};
req.post = await new Promise((resolve, _, data = "") => req
.on("data", d => void (data += d))
.on("end", () => void resolve(Object.fromEntries(Object.entries(querystring.parse(data)).map(([k, v]) => {
try {
return [k, decodeURIComponent(v)];
} catch(err) {
return [k, v];
.on("end", () => {
if(req.headers['content-type'] == "application/json") {
try {
return void resolve(JSON.parse(data));
} catch(err) {}
}
})))));
void resolve(Object.fromEntries(Object.entries(querystring.parse(data)).map(([k, v]) => {
try {
return [k, decodeURIComponent(v)];
} catch(err) {
return [k, v];
}
})));
}));
res.reply = ({
code = 200,
@ -68,13 +75,29 @@ import router from "./inc/router.mjs";
}).end();
}
}
!(r = router.routes.getRoute(req.url.pathname, req.method)) ? res.writeHead(404).end(`404 - ${req.method} ${req.url.pathname}`) : await r(req, res);
console.log([
`[${(new Date()).toLocaleTimeString()}]`,
`${(process.hrtime(t_start)[1] / 1e6).toFixed(2)}ms`,
`${req.method} ${res.statusCode}`,
req.url.pathname].map(e=>e.toString().padEnd(15)).join(""));
req.url.pathname
].map(e => e.toString().padEnd(15)).join(""));
if(r = router.routes.getRoute(req.url.pathname, req.method)) {
if(r.meddlware) {
const tmp = r.meddlware(req, req);
if(tmp.redirect)
return res.redirect(tmp.redirect);
if(!tmp.success)
return res.reply({ body: tmp.msg });
}
await r.f(req, res);
}
else {
res
.writeHead(404)
.end(`404 - ${req.method} ${req.url.pathname}`);
}
}).listen(cfg.websrv.port, () => setTimeout(() => {
console.log(`f0ck is listening on port ${cfg.websrv.port}.`);
}, 500));