318 lines
8.1 KiB
JavaScript
318 lines
8.1 KiB
JavaScript
import sql from "../sql.mjs";
|
|
import lib from "../lib.mjs";
|
|
|
|
const allowedMimes = [ "audio", "image", "video", "%" ];
|
|
const auth = async (req, res, next) => {
|
|
if(!req.session) {
|
|
return res.reply({
|
|
code: 401,
|
|
body: "401 - Unauthorized"
|
|
});
|
|
}
|
|
return next();
|
|
};
|
|
|
|
export default (router, tpl) => {
|
|
router.group(/^\/api\/v2/, group => {
|
|
|
|
group.get(/$/, (req, res) => {
|
|
res.end("api lol");
|
|
});
|
|
|
|
group.get(/\/random(\/user\/.+|\/image|\/video|\/audio)?$/, async (req, res) => {
|
|
const user = req.url.split[3] === "user" ? req.url.split[4] : "%";
|
|
const mime = (allowedMimes.filter(n => req.url.split[3]?.startsWith(n))[0] ? req.url.split[3] : "") + "%";
|
|
|
|
const rows = await sql("items")
|
|
.orderByRaw("rand()")
|
|
.limit(1)
|
|
.where("mime", "ilike", mime)
|
|
.andWhere("username", "ilike", user);
|
|
|
|
return res.json({
|
|
success: rows.length > 0,
|
|
items: rows.length > 0 ? rows[0] : []
|
|
});
|
|
});
|
|
|
|
group.get(/\/p\/([0-9]+)/, async (req, res) => { // legacy
|
|
let eps = 100;
|
|
let id = +req.url.split[3];
|
|
|
|
const rows = await sql("items").where("id", "<", id).orderBy("id", "desc").limit(eps);
|
|
|
|
const items = {
|
|
items: rows,
|
|
last: rows[rows.length - 1].id
|
|
};
|
|
|
|
return res.json({
|
|
success: true,
|
|
items
|
|
});
|
|
});
|
|
|
|
group.get(/\/item\/[0-9]+$/, async (req, res) => {
|
|
const id = +req.url.split[3];
|
|
|
|
const item = await sql("items").where("id", id).limit(1);
|
|
const next = await sql("items").select("id").where("id", ">", id).orderBy("id").limit(1);
|
|
const prev = await sql("items").select("id").where("id", "<", id).orderBy("id", "desc").limit(1);
|
|
|
|
if(item.length === 0) {
|
|
return res.json({
|
|
success: false,
|
|
msg: 'no items found'
|
|
});
|
|
}
|
|
|
|
const rows = {
|
|
...item[0],
|
|
...{
|
|
next: next[0]?.id ?? null,
|
|
prev: prev[0]?.id ?? null
|
|
}
|
|
};
|
|
|
|
return res.json({
|
|
success: true,
|
|
rows
|
|
});
|
|
});
|
|
|
|
group.get(/\/user\/.*(\/\d+)?$/, async (req, res) => {
|
|
const user = req.url.split[3];
|
|
const eps = +req.url.split[4] || 50;
|
|
|
|
const rows = await sql("items")
|
|
.select("id", "mime", "size", "src", "stamp", "userchannel", "username", "usernetwork")
|
|
.where("username", user)
|
|
.orderBy("stamp", "desc")
|
|
.limit(eps);
|
|
|
|
return res.json({
|
|
success: rows.length > 0,
|
|
items: rows.length > 0 ? rows : []
|
|
});
|
|
});
|
|
|
|
// adminzeugs
|
|
group.delete(/\/admin\/(?<postid>\d+)\/tags\/(?<tagname>.*)/, auth, async (req, res) => {
|
|
// delete tag
|
|
if(!req.params.postid || !req.params.tagname) {
|
|
return res.json({
|
|
success: false,
|
|
msg: 'missing postid or tagname'
|
|
});
|
|
}
|
|
|
|
const postid = +req.params.postid;
|
|
const tagname = decodeURIComponent(req.params.tagname);
|
|
|
|
const tags = await lib.getTags(postid);
|
|
|
|
const tagid = tags.filter(t => t.tag === tagname)[0]?.id ?? null;
|
|
|
|
if(!tagid) {
|
|
return res.json({
|
|
success: false,
|
|
msg: 'tag is not assigned',
|
|
tags: await lib.getTags(postid)
|
|
});
|
|
}
|
|
|
|
let q = sql("tags_assign").where("tag_id", tagid).andWhere("item_id", postid).del();
|
|
if(req.session.level < 50)
|
|
q = q.andWhere("user_id", req.session.id);
|
|
const reply = !!(await q);
|
|
|
|
return res.json({
|
|
success: reply,
|
|
tagid,
|
|
tags: await lib.getTags(postid)
|
|
})
|
|
});
|
|
|
|
group.post(/\/admin\/(?<postid>\d+)\/tags/, auth, async (req, res) => {
|
|
// assign and/or create tag
|
|
if(!req.params.postid || !req.post.tagname) {
|
|
return res.json({
|
|
success: false,
|
|
msg: 'missing postid or tag'
|
|
});
|
|
}
|
|
|
|
const postid = +req.params.postid;
|
|
const tagname = req.post.tagname?.trim();
|
|
|
|
if(tagname.length >= 45) {
|
|
return res.json({
|
|
success: false,
|
|
msg: 'tag is too long!'
|
|
});
|
|
}
|
|
|
|
try {
|
|
let tagid = (
|
|
await sql("tags")
|
|
.select("id")
|
|
.whereRaw("normalized = slugify(?)", [ tagname ])
|
|
)?.[0]?.id;
|
|
|
|
if(!tagid) { // create new tag
|
|
tagid = (await sql("tags").returning("id").insert({
|
|
tag: tagname
|
|
}))[0];
|
|
}
|
|
await sql("tags_assign").insert({
|
|
tag_id: tagid,
|
|
item_id: postid,
|
|
user_id: req.session.id
|
|
});
|
|
} catch(err) {
|
|
return res.json({
|
|
success: false,
|
|
msg: err.message,
|
|
tags: await lib.getTags(postid)
|
|
});
|
|
}
|
|
|
|
return res.json({
|
|
success: true,
|
|
postid: postid,
|
|
tag: tagname,
|
|
tags: await lib.getTags(postid)
|
|
});
|
|
});
|
|
|
|
group.get(/\/admin\/(?<postid>\d+)\/tags$/, auth, async (req, res) => {
|
|
// get tags
|
|
if(!req.params.postid) {
|
|
return res.json({
|
|
success: false,
|
|
msg: 'missing postid'
|
|
});
|
|
}
|
|
|
|
return res.json({
|
|
success: true,
|
|
tags: await lib.getTags(+req.params.postid)
|
|
});
|
|
});
|
|
|
|
group.put(/\/admin\/(?<postid>\d+)\/tags\/toggle$/, auth, async (req, res) => {
|
|
// xD
|
|
if(!req.params.postid) {
|
|
return res.json({
|
|
success: false,
|
|
msg: 'missing postid'
|
|
});
|
|
}
|
|
|
|
const postid = +req.params.postid;
|
|
|
|
if(!(await lib.getTags(postid)).filter(tag => [1,2].includes(tag.id)).length) {
|
|
// insert
|
|
await sql('tags_assign').insert({
|
|
item_id: postid,
|
|
tag_id: 1,
|
|
user_id: req.session.id
|
|
});
|
|
}
|
|
else {
|
|
// update
|
|
await sql('tags_assign')
|
|
.update({
|
|
tag_id: sql.raw('(array[2,1])[tag_id]')
|
|
})
|
|
.whereRaw('tag_id = any(array[1,2])')
|
|
.andWhere('item_id', postid);
|
|
}
|
|
|
|
return res.json({
|
|
success: true,
|
|
tags: await lib.getTags(postid)
|
|
});
|
|
});
|
|
|
|
group.get(/\/admin\/tags\/suggest$/, auth, async (req, res) => {
|
|
const reply = {
|
|
success: false,
|
|
suggestions: {}
|
|
};
|
|
|
|
const searchString = req.url.qs.q;
|
|
|
|
if(searchString?.length <= 1) {
|
|
reply.error = 'too short lol';
|
|
return res.json(reply);
|
|
}
|
|
|
|
try {
|
|
const q = await sql('tags')
|
|
.select('tag', sql.raw('count(tags_assign.tag_id) as tagged'))
|
|
.leftJoin('tags_assign', 'tags_assign.tag_id', 'tags.id')
|
|
.whereRaw("normalized like '%' || slugify(?) || '%'", [ searchString ])
|
|
.groupBy('tags.id')
|
|
.orderBy('tagged', 'desc')
|
|
.limit(15);
|
|
reply.success = true;
|
|
reply.suggestions = q;
|
|
} catch(err) {
|
|
reply.error = err.msg;
|
|
}
|
|
|
|
return res.json(reply);
|
|
});
|
|
|
|
group.post(/\/admin\/deletepost$/, auth, async (req, res) => {
|
|
if(!req.post.postid) {
|
|
return res.json({
|
|
success: false,
|
|
msg: 'no postid'
|
|
});
|
|
}
|
|
const postid = +req.post.postid;
|
|
|
|
await sql("items").where("id", postid).del();
|
|
|
|
res.json({
|
|
success: true
|
|
});
|
|
});
|
|
|
|
group.post(/\/admin\/togglefav$/, auth, async (req, res) => {
|
|
const postid = +req.post.postid;
|
|
|
|
let favs = await sql('favorites').select('user_id').where('item_id', postid);
|
|
|
|
if(Object.values(favs).filter(u => u.user_id === req.session.id)[0]) {
|
|
// del fav
|
|
await sql('favorites').where('user_id', req.session.id).andWhere('item_id', postid).del();
|
|
}
|
|
else {
|
|
// add fav
|
|
await sql('favorites').insert({
|
|
item_id: postid,
|
|
user_id: req.session.id
|
|
});
|
|
}
|
|
|
|
favs = await sql('favorites')
|
|
.select('user.user', 'user_options.avatar')
|
|
.leftJoin('user', 'user.id', 'favorites.user_id')
|
|
.leftJoin('user_options', 'user_options.user_id', 'favorites.user_id')
|
|
.where('favorites.item_id', postid);
|
|
|
|
return res.json({
|
|
success: true,
|
|
itemid: postid,
|
|
favs
|
|
});
|
|
});
|
|
|
|
});
|
|
|
|
return router;
|
|
};
|