f0ckv2/src/inc/lib.mjs
2021-12-20 17:55:47 +01:00

110 lines
3.4 KiB
JavaScript

import crypto from "crypto";
import util from "util";
import sql from "./sql.mjs";
const scrypt = util.promisify(crypto.scrypt);
const epochs = [
["year", 31536000],
["month", 2592000],
["day", 86400],
["hour", 3600],
["minute", 60],
["second", 1]
];
const getDuration = timeAgoInSeconds => {
for(let [name, seconds] of epochs) {
const interval = ~~(timeAgoInSeconds / seconds);
if(interval >= 1) return {
interval: interval,
epoch: name
};
}
};
export default new class {
formatSize(size, i = ~~(Math.log(size) / Math.log(1024))) {
return (size / Math.pow(1024, i)).toFixed(2) * 1 + " " + ["B", "kB", "MB", "GB", "TB"][i];
};
calcSpeed(b, s) {
return (Math.round((b * 8 / s / 1e6) * 1e4) / 1e4);
};
timeAgo(date) {
const { interval, epoch } = getDuration(~~((new Date() - new Date(date)) / 1e3));
return `${interval} ${epoch}${interval === 1 ? "" : "s"} ago`;
};
md5(str) {
return crypto.createHash('md5').update(str).digest("hex");
};
getMode(mode) {
let tmp;
switch(mode) {
case 1: // nsfw
tmp = "items.id in (select item_id from tags_assign where tag_id = 2 group by item_id)";
break;
case 2: // untagged
tmp = "items.id not in (select item_id from tags_assign group by item_id)";
break;
case 3: // all
tmp = "";
break;
default: // sfw
tmp = "items.id in (select item_id from tags_assign where tag_id = 1 group by item_id)";
break;
}
return tmp;
};
createID() {
return crypto.randomBytes(16).toString("hex") + Date.now().toString(24);
};
genLink(env) {
const link = [];
if(env.user) link.push("user", env.user);
if(env.tag) link.push("tag", env.tag);
if(env.mime.length > 2) link.push(env.mime);
if(env.page) link.push("p", env.page);
return link.join("/");
};
parseTag(tag) {
if(!tag)
return null;
return tag
.replace(/%20/g, " ");
}
// async funcs
async countf0cks() {
const tagged = (await sql("items").whereRaw("id in (select item_id from tags_assign group by item_id)").count("* as total"))[0].total;
const untagged = (await sql("items").whereRaw("id not in (select item_id from tags_assign group by item_id)").count("* as total"))[0].total;
const sfw = (await sql("items").whereRaw("id in (select item_id from tags_assign where tag_id = 1 group by item_id)").count("* as total"))[0].total;
const nsfw = (await sql("items").whereRaw("id in (select item_id from tags_assign where tag_id = 2 group by item_id)").count("* as total"))[0].total;
return {
tagged,
untagged,
total: tagged + untagged,
sfw,
nsfw
};
};
async hash(str) {
const salt = crypto.randomBytes(16).toString("hex");
const derivedKey = await scrypt(str, salt, 64);
return "$f0ck$" + salt + ":" + derivedKey.toString("hex");
};
async verify(str, hash) {
const [ salt, key ] = hash.substring(6).split(":");
const keyBuffer = Buffer.from(key, "hex");
const derivedKey = await scrypt(str, salt, 64);
return crypto.timingSafeEqual(keyBuffer, derivedKey);
};
async getTags(itemid) {
const tags = await sql("tags_assign")
.leftJoin("tags", "tags.id", "tags_assign.tag_id")
.where("tags_assign.item_id", itemid);
for(let t = 0; t < tags.length; t++)
tags[t].tag = tags[t].tag.replace(/[\u00A0-\u9999<>\&]/g, i => '&#'+i.charCodeAt(0)+';');
return tags;
};
};