sirx: und weg damit :D
This commit is contained in:
11
src/inc/meddlware.mjs
Normal file
11
src/inc/meddlware.mjs
Normal file
@ -0,0 +1,11 @@
|
||||
export const auth = (req, res) => {
|
||||
if(!req.session) {
|
||||
return {
|
||||
success: false,
|
||||
redirect: "/"
|
||||
};
|
||||
}
|
||||
return {
|
||||
success: true
|
||||
};
|
||||
};
|
@ -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];
|
||||
};
|
||||
|
@ -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)
|
||||
});
|
||||
});
|
||||
|
@ -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
|
||||
})});
|
||||
});
|
||||
|
35
src/inc/routes/inc/search.mjs
Normal file
35
src/inc/routes/inc/search.mjs
Normal 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);
|
||||
};
|
@ -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));
|
||||
|
Reference in New Issue
Block a user