|
@@ -0,0 +1,636 @@
|
|
|
+const express = require("express");
|
|
|
+const fs = require("node:fs");
|
|
|
+const path = require("node:path");
|
|
|
+const supabase = require("@supabase/supabase-js");
|
|
|
+const cookie_parser = require("cookie-parser");
|
|
|
+const multer = require("multer");
|
|
|
+const app = express();
|
|
|
+require("dotenv").config();
|
|
|
+
|
|
|
+const webhookURL = process.env.WEBHOOK_URL;
|
|
|
+const utils = require("./utils.js");
|
|
|
+const url = "https://skibidihub.buttplugstudios.xyz"
|
|
|
+
|
|
|
+let ipBlacklist = JSON.parse(fs.readFileSync("./ipbans.json"));
|
|
|
+fs.watch("./ipbans.json", () => {
|
|
|
+ console.log("Reloading IP Bans...");
|
|
|
+ ipBlacklist = JSON.parse(fs.readFileSync("./ipbans.json"));
|
|
|
+});
|
|
|
+
|
|
|
+const port = 3000;
|
|
|
+const storage = multer.diskStorage({
|
|
|
+ destination: function (req, file, cb) {
|
|
|
+ try {
|
|
|
+ // Validations
|
|
|
+ if (!utils.checkBodyVideo(req.body)) throw new Error("invalid video body");
|
|
|
+ if (!utils.checkToken(req, "/api/upload multer")) throw new Error("unauthorized");
|
|
|
+
|
|
|
+ if(!req.skibidihub_id) req.skibidihub_id = utils.nanoid(7);
|
|
|
+ console.log("Video ID:", req.skibidihub_id);
|
|
|
+
|
|
|
+ // Check if the directory exists, and create it if it doesn't
|
|
|
+ const dir = path.join(__dirname, "videos", req.skibidihub_id);
|
|
|
+ if (!utils.videoExists(req.skibidihub_id)) {
|
|
|
+ console.log("Directory does not exist, creating:", dir);
|
|
|
+ fs.mkdirSync(dir, { recursive: true });
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set the destination path for multer
|
|
|
+ cb(null, dir);
|
|
|
+ } catch (err) {
|
|
|
+ console.log("Error in destination function:", err);
|
|
|
+ cb(err);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ filename: function (req, file, cb) {
|
|
|
+ let filename;
|
|
|
+ if (file.fieldname === "video") {
|
|
|
+ filename = "video.mp4";
|
|
|
+ } else if (file.fieldname === "thumbnail") {
|
|
|
+ filename = "thumbnail.jpg";
|
|
|
+ }
|
|
|
+ console.log("Saving file with filename:", filename);
|
|
|
+ cb(null, filename);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const upload = multer({
|
|
|
+ storage: storage,
|
|
|
+ limits: { fileSize: 1000000 * 250 /* 250MB in bytes */ }
|
|
|
+});
|
|
|
+
|
|
|
+const client = supabase.createClient(
|
|
|
+ process.env.SUPABASE_URL,
|
|
|
+ process.env.SUPABASE_KEY
|
|
|
+);
|
|
|
+
|
|
|
+const ipwareObject = require("@fullerstack/nax-ipware");
|
|
|
+const sunset = JSON.parse(fs.readFileSync(path.join(__dirname, "sunset.json")));
|
|
|
+const ipware = new ipwareObject.Ipware();
|
|
|
+app.use(function(req, res, next) {
|
|
|
+ req.ipInfo = ipware.getClientIP(req);
|
|
|
+
|
|
|
+ if (new Date().getTime() >= sunset.timestamp && sunset.sunset == true) {
|
|
|
+ if(req.path == "/assets/piss baby.mp4") {
|
|
|
+ if (ipBlacklist.includes(req.ipInfo.ip)) {
|
|
|
+ res.setHeader("Cache-Control", "no-cache");
|
|
|
+ return res.sendFile(path.join(__dirname, path.join("www", "down.html")));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return res.sendFile(path.join(__dirname, path.join("www", "sunset.html")));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(ipBlacklist.includes(req.ipInfo.ip)) {
|
|
|
+ res.setHeader("Cache-Control", "no-cache");
|
|
|
+ return res.sendFile(path.join(__dirname, path.join("www", "down.html")));
|
|
|
+ }
|
|
|
+
|
|
|
+ next();
|
|
|
+});
|
|
|
+
|
|
|
+app.use(express.static("www")); // Static folder
|
|
|
+app.use(express.json()); // JSON body parser
|
|
|
+app.use(cookie_parser()); // Cookie parser
|
|
|
+
|
|
|
+// User facing URL's
|
|
|
+app.get("/", (req, res) => {
|
|
|
+ res.sendFile(path.join(__dirname, path.join("www", "index.html")));
|
|
|
+});
|
|
|
+
|
|
|
+app.get("/login", (req, res) => {
|
|
|
+ res.sendFile(path.join(__dirname, path.join("www", "login.html")));
|
|
|
+});
|
|
|
+
|
|
|
+app.get("/upload", (req, res) => {
|
|
|
+ res.sendFile(path.join(__dirname, path.join("www", "upload.html")));
|
|
|
+})
|
|
|
+
|
|
|
+app.get("/contact", (req, res) => {
|
|
|
+ res.sendFile(path.join(__dirname, path.join("www", "contact.html")));
|
|
|
+})
|
|
|
+
|
|
|
+app.get("/editProfile", (req, res) => {
|
|
|
+ res.sendFile(path.join(__dirname, path.join("www", "editProfile.html")));
|
|
|
+});
|
|
|
+
|
|
|
+app.get("/search", (req, res) => {
|
|
|
+ res.sendFile(path.join(__dirname, path.join("www", "search.html")));
|
|
|
+});
|
|
|
+
|
|
|
+app.set('view engine', 'ejs');
|
|
|
+app.get("/video/:id", async (req, res) => {
|
|
|
+ if(utils.discordCheck(req) && utils.videoExists(req.params.id)) {
|
|
|
+ const videoInfo = await utils.videoInfo(req.params.id);
|
|
|
+ if(isNaN(videoInfo)) {
|
|
|
+ return res.render("video", {
|
|
|
+ video: `${url}/api/video/${req.params.id}.mp4`,
|
|
|
+ video_name: videoInfo.title,
|
|
|
+ description: videoInfo.description,
|
|
|
+ url: url,
|
|
|
+ author_url: `${url}/api/oembed/?author_name=${videoInfo.uploader}&author_url=${url}/user/${encodeURIComponent(videoInfo.uploader)}`
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!utils.videoExists(req.params.id) && utils.checkToken(req, "/video/:id")) {
|
|
|
+ return res.sendFile(path.join(__dirname, path.join("www", "404.html")));
|
|
|
+ }
|
|
|
+
|
|
|
+ res.sendFile(path.join(__dirname, path.join("www", "video.html")));
|
|
|
+});
|
|
|
+
|
|
|
+app.get("/user/:user", (req, res) => {
|
|
|
+ if(!utils.checkToken(req, "/user/:user")) {
|
|
|
+ return res.sendFile(path.join(__dirname, path.join("www", "user.html")));
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check if user exists
|
|
|
+ client.from("users").select().eq("name", decodeURIComponent(req.params.user)).then(data => {
|
|
|
+ if(data.error) {
|
|
|
+ return res.sendFile(path.join(__dirname, path.join("www", "404.html")));
|
|
|
+ } else if (data.status != 200) {
|
|
|
+ return res.sendFile(path.join(__dirname, path.join("www", "404.html")));
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!data.data[0]) return res.sendFile(path.join(__dirname, path.join("www", "404.html")));
|
|
|
+ res.sendFile(path.join(__dirname, path.join("www", "user.html")));
|
|
|
+ })
|
|
|
+});
|
|
|
+
|
|
|
+// API //
|
|
|
+
|
|
|
+function handleVideoAPI(req, res) {
|
|
|
+ if(!utils.checkToken(req, "/api/video/:id") && !utils.discordCheck(req)) {
|
|
|
+ return res.sendFile(
|
|
|
+ path.join(
|
|
|
+ __dirname,
|
|
|
+ path.join("www", path.join("assets", path.join("troll", "video.mp4")))
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ const videoPath = path.join(__dirname, path.join("videos", path.join(req.params.id, "video.mp4")));
|
|
|
+ if(!fs.existsSync(videoPath)) return res.sendStatus(404);
|
|
|
+
|
|
|
+ const stat = fs.statSync(videoPath);
|
|
|
+ const fileSize = stat.size;
|
|
|
+ const range = req.headers.range;
|
|
|
+
|
|
|
+ console.log('Requested Range:', range); // Log the range for debugging
|
|
|
+
|
|
|
+ if (range) {
|
|
|
+ const parts = range.replace(/bytes=/, "").split("-");
|
|
|
+ let start = parseInt(parts[0], 10);
|
|
|
+ let end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
|
|
|
+
|
|
|
+ // Handle the case where range is 0-1
|
|
|
+ if (start === 0 && end === 1) {
|
|
|
+ end = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ const chunksize = (end - start) + 1;
|
|
|
+ const file = fs.createReadStream(videoPath, {start, end});
|
|
|
+ const head = {
|
|
|
+ 'Content-Range': `bytes ${start}-${end}/${fileSize}`,
|
|
|
+ 'Accept-Ranges': 'bytes',
|
|
|
+ 'Content-Length': chunksize,
|
|
|
+ 'Content-Type': 'video/mp4',
|
|
|
+ };
|
|
|
+ res.writeHead(206, head);
|
|
|
+ file.pipe(res);
|
|
|
+ } else {
|
|
|
+ const head = {
|
|
|
+ 'Content-Length': fileSize,
|
|
|
+ 'Content-Type': 'video/mp4',
|
|
|
+ 'Accept-Ranges': 'bytes',
|
|
|
+ };
|
|
|
+ res.writeHead(200, head);
|
|
|
+ fs.createReadStream(videoPath).pipe(res);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// Get an mp4 file according to its video ID.
|
|
|
+app.get('/api/video/:id*.mp4', handleVideoAPI);
|
|
|
+app.get("/api/video/:id", handleVideoAPI);
|
|
|
+
|
|
|
+// OEmbed
|
|
|
+const oembed = (provider_name, provider_url, author_name, author_url, url) => {
|
|
|
+ const baseObject = {
|
|
|
+ version: '1.0',
|
|
|
+ };
|
|
|
+ if (provider_name && provider_url) {
|
|
|
+ baseObject.provider_name = provider_name;
|
|
|
+ baseObject.provider_url = provider_url;
|
|
|
+ }
|
|
|
+ if (author_name) {
|
|
|
+ baseObject.author_name = author_name;
|
|
|
+ }
|
|
|
+ if (author_url) {
|
|
|
+ baseObject.author_url = author_url;
|
|
|
+ }
|
|
|
+ if (url) {
|
|
|
+ baseObject.url = url;
|
|
|
+ }
|
|
|
+ return baseObject;
|
|
|
+};
|
|
|
+
|
|
|
+app.get('/api/oembed', (req, res) => {
|
|
|
+ const {
|
|
|
+ provider_name,
|
|
|
+ provider_url,
|
|
|
+ author_name,
|
|
|
+ author_url,
|
|
|
+ url,
|
|
|
+ } = req.query;
|
|
|
+ return res.status(200).send(oembed(provider_name, provider_url, author_name, author_url, url));
|
|
|
+});
|
|
|
+
|
|
|
+// Get a videos thumbnail according to its video ID.
|
|
|
+app.get("/api/thumbnail/:id", (req, res) => {
|
|
|
+ if (!utils.checkToken(req, "/api/thumbnail/:id")) {
|
|
|
+ let images = fs.readdirSync(
|
|
|
+ path.join(__dirname, path.join("www", path.join("assets", "troll")))
|
|
|
+ );
|
|
|
+ res.sendFile(
|
|
|
+ path.join(
|
|
|
+ __dirname,
|
|
|
+ path.join(
|
|
|
+ "www",
|
|
|
+ path.join(
|
|
|
+ "assets",
|
|
|
+ path.join("troll", images[utils.getRandomInt(images.length - 1)])
|
|
|
+ )
|
|
|
+ )
|
|
|
+ )
|
|
|
+ );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const thumbnail = utils.getThumbnail(req.params.id);
|
|
|
+ if(thumbnail) return res.sendFile(thumbnail);
|
|
|
+ if(!thumbnail) return res.sendStatus(404);
|
|
|
+});
|
|
|
+
|
|
|
+// Get a videos thumbnail according to its video ID.
|
|
|
+app.get("/api/webhookThumbnail/:id", (req, res) => {
|
|
|
+ const thumbnail = utils.getThumbnail(req.params.id);
|
|
|
+ if(thumbnail) return res.sendFile(thumbnail);
|
|
|
+ if(!thumbnail) return res.sendStatus(404);
|
|
|
+});
|
|
|
+
|
|
|
+// Get the info for a video according to its video ID.
|
|
|
+app.get("/api/videoInfo/:id", async (req, res) => {
|
|
|
+ if(!utils.checkToken(req, "/api/videoInfo/:id")) {
|
|
|
+ let newData = {};
|
|
|
+ newData.title = utils.fakeTitleList[utils.getRandomInt(utils.fakeTitleList.length)]
|
|
|
+ newData.description = "SIGN IN to see this EPIC content"
|
|
|
+ newData.likes = "69"
|
|
|
+ newData.dislikes = "0"
|
|
|
+ newData.uploader = "SIGN IN to see this EPIC content"
|
|
|
+ newData.uploaded_at = new Date().toISOString().toString();
|
|
|
+ return res.send(newData);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!utils.videoExists(req.params.id)) return res.sendStatus(404);
|
|
|
+
|
|
|
+ const videoInfo = await utils.videoInfo(req.params.id);
|
|
|
+ if(isNaN(videoInfo)) {
|
|
|
+ return res.send(videoInfo);
|
|
|
+ } else {
|
|
|
+ return res.sendStatus(videoInfo);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// Pulls the user information from the database and returns it.
|
|
|
+app.get("/api/userInfo/:id", (req, res) => {
|
|
|
+ if(!utils.checkToken(req, "/api/userInfo/:id")) {
|
|
|
+ let data = {
|
|
|
+ name: "SIGN IN to see this EPIC CONTENT",
|
|
|
+ subscribers: 999,
|
|
|
+ social_score: 999,
|
|
|
+ description: "SIGN IN to see this EPIC content",
|
|
|
+ verified: true
|
|
|
+ }
|
|
|
+
|
|
|
+ return res.send(data);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ client.from("users").select().eq("name", decodeURIComponent(req.params.id)).then(data => {
|
|
|
+ if(data.error) {
|
|
|
+ return res.sendStatus(400);
|
|
|
+ } else if (data.status != 200) {
|
|
|
+ return res.sendStatus(data.status);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!data.data[0]) return res.sendStatus(400);
|
|
|
+ return res.send(data.data[0]);
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+// Subscribes to a user
|
|
|
+app.get("/api/subscribe/:id", async (req, res) => {
|
|
|
+ if(!utils.checkToken(req)) return res.sendStatus(401);
|
|
|
+ if(!utils.userExists(decodeURIComponent(req.params.id))) return res.sendStatus(400);
|
|
|
+
|
|
|
+ const subscribersData = await client
|
|
|
+ .from("users")
|
|
|
+ .select("subscribers")
|
|
|
+ .eq("name", decodeURIComponent(req.params.id));
|
|
|
+
|
|
|
+ const subscribers = subscribersData["data"][0]["subscribers"] + 1;
|
|
|
+
|
|
|
+ client.from("users").update({
|
|
|
+ subscribers: subscribers
|
|
|
+ }).eq("name", decodeURIComponent(req.params.id)).then(data => {
|
|
|
+ if(data.error) {
|
|
|
+ return res.sendStatus(400);
|
|
|
+ } else if (data.status != 204) {
|
|
|
+ return res.sendStatus(data.status);
|
|
|
+ }
|
|
|
+
|
|
|
+ return res.sendStatus(200);
|
|
|
+ })
|
|
|
+});
|
|
|
+
|
|
|
+// Login endpoints (Just handles user creation)
|
|
|
+app.post("/api/login", async (req, res) => {
|
|
|
+ if(!req.body.user) return res.sendStatus(400);
|
|
|
+ const ipInfo = ipware.getClientIP(req);
|
|
|
+
|
|
|
+ // If user doesn't exist, create the user.
|
|
|
+ if(!await utils.userExists(req.body.user)) {
|
|
|
+ console.log(`User ${req.body.user} doesn't exist. Creating the user...`);
|
|
|
+ await client.from("users").insert({
|
|
|
+ name: req.body.user
|
|
|
+ }).then(data => {
|
|
|
+ if(data.error) {
|
|
|
+ return res.status(500).send(data);
|
|
|
+ } else if(data.status != 201) {
|
|
|
+ return res.status(500).send(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(`User created successfully. IP: ${ipInfo.ip}`);
|
|
|
+ return res.sendStatus(200);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ console.log(`User ${req.body.user} already exists. Logging in... IP: ${ipInfo.ip}`);
|
|
|
+ return res.sendStatus(200);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+app.post("/api/editUser", async (req, res) => {
|
|
|
+ // Validate request
|
|
|
+ const user = utils.checkUserToken(req, "/api/editUser");
|
|
|
+ if(!user.value) return res.status(401).json({message: "you need to login to edit your user page"});
|
|
|
+ if(!req.body.description && !req.body.website) return res.status(400).json({message: "invalid form data"});
|
|
|
+ if(req.body.website && !utils.isValidUrl(req.body.website)) return res.status(400).json({message: "invalid website"});
|
|
|
+
|
|
|
+ // Update user
|
|
|
+ await client.from("users").update({
|
|
|
+ description: req.body.description,
|
|
|
+ website: req.body.website,
|
|
|
+ }).eq("name", user.user).then(data => {
|
|
|
+ if(data.error) {
|
|
|
+ return res.status(500).send(data);
|
|
|
+ } else if(data.status != 204) {
|
|
|
+ return res.status(500).send(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ return res.sendStatus(200);
|
|
|
+ })
|
|
|
+});
|
|
|
+
|
|
|
+// Get the comments for a video according to its video ID.
|
|
|
+app.get("/api/comments/:videoID", (req, res) => {
|
|
|
+ if(!utils.checkToken(req, "/api/comments/:videoID")) {
|
|
|
+ let comments = [];
|
|
|
+ for(let i = 0; i < 8; i++) {
|
|
|
+ let comment = {};
|
|
|
+ comment.text = utils.fakeCommentList[utils.getRandomInt(utils.fakeCommentList.length)]
|
|
|
+ comment.commenter = "SIGN IN to see this EPIC content!";
|
|
|
+ let date = new Date();
|
|
|
+ date.setTime(1005286084);
|
|
|
+ comment.created_at = date.toISOString();
|
|
|
+ comments.push(comment);
|
|
|
+ }
|
|
|
+
|
|
|
+ return res.send(comments);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!utils.videoExists(req.params.videoID)) return res.sendStatus(404);
|
|
|
+
|
|
|
+ client
|
|
|
+ .from("comments")
|
|
|
+ .select()
|
|
|
+ .eq("video_id", req.params.videoID)
|
|
|
+ .then((data) => {
|
|
|
+ if (data.error) {
|
|
|
+ res.sendStatus(400);
|
|
|
+ } else if (data.status != 200) {
|
|
|
+ res.sendStatus(data.status);
|
|
|
+ }
|
|
|
+
|
|
|
+ res.send(data["data"]);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+// Get a list of all videos
|
|
|
+app.get("/api/getAllVideos", (req, res) => {
|
|
|
+ if(!utils.checkToken(req, "/api/getAllVideos/")) {
|
|
|
+ let newData = [];
|
|
|
+ for(let i = 0; i < 12; i++) {
|
|
|
+ let temp = {};
|
|
|
+ temp.description = "SIGN IN to see this EPIC content"
|
|
|
+ temp.title = utils.fakeTitleList[utils.getRandomInt(utils.fakeTitleList.length)]
|
|
|
+ temp.uploader = "SIGN IN to see this EPIC content";
|
|
|
+ temp.id = utils.nanoid(7);
|
|
|
+ newData.push(temp);
|
|
|
+ }
|
|
|
+
|
|
|
+ return res.send(newData);
|
|
|
+ }
|
|
|
+
|
|
|
+ client
|
|
|
+ .from("videos")
|
|
|
+ .select()
|
|
|
+ .then((data) => {
|
|
|
+ if (data.error) {
|
|
|
+ return res.sendStatus(400);
|
|
|
+ } else if (data.status != 200) {
|
|
|
+ return res.sendStatus(data.status);
|
|
|
+ }
|
|
|
+
|
|
|
+ return res.send(data["data"]);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+// Search endpoint
|
|
|
+app.post("/api/search", (req, res) => {
|
|
|
+ if(!utils.checkToken(req)) return res.sendStatus(401);
|
|
|
+ if(!req.body.query) return res.sendStatus(400);
|
|
|
+ client
|
|
|
+ .from("videos")
|
|
|
+ .select()
|
|
|
+ .then((response) => {
|
|
|
+ if (response.error) {
|
|
|
+ return res.sendStatus(400);
|
|
|
+ } else if (response.status != 200) {
|
|
|
+ return res.sendStatus(response.status);
|
|
|
+ }
|
|
|
+
|
|
|
+ let results = [];
|
|
|
+ response.data.forEach(video => {
|
|
|
+ if(video.title.startsWith(req.body.query.toLowerCase()) || video.uploader.startsWith(req.body.query.toLowerCase())) results.push(video);
|
|
|
+ })
|
|
|
+
|
|
|
+ return res.send(results);
|
|
|
+ });
|
|
|
+})
|
|
|
+
|
|
|
+// Send a comment
|
|
|
+app.post("/api/comment", async (req, res) => {
|
|
|
+ if (!utils.checkToken(req, "/api/comment")) return res.sendStatus(401);
|
|
|
+
|
|
|
+ // Sanity chekcs
|
|
|
+ if(!req.body.commenter) return res.sendStatus(400);
|
|
|
+ if(!req.body.videoID) return res.sendStatus(400);
|
|
|
+ if(!req.body.text) return res.sendStatus(400);
|
|
|
+
|
|
|
+
|
|
|
+ if(req.body.text.trim() == "") return res.sendStatus(400);
|
|
|
+ if(!utils.videoExists(req.body.videoID)) return res.sendStatus(404);
|
|
|
+
|
|
|
+ client
|
|
|
+ .from("comments")
|
|
|
+ .insert({
|
|
|
+ commenter: req.body.commenter,
|
|
|
+ video_id: req.body.videoID,
|
|
|
+ text: req.body.text,
|
|
|
+ })
|
|
|
+ .then((data) => {
|
|
|
+ res.send(data);
|
|
|
+
|
|
|
+ // Discord webhook
|
|
|
+ utils.sendWebhook(
|
|
|
+ "new comment guys",
|
|
|
+ "New COMMENT!!!!!",
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "id": 220464536,
|
|
|
+ "description": req.body.text.trim(),
|
|
|
+ "fields": [],
|
|
|
+ "title": `New comment on video ${req.body.videoID}!`,
|
|
|
+ "author": {
|
|
|
+ "name": req.body.commenter,
|
|
|
+ "url": `http://skibidihub.buttplugstudios.xyz/user/${encodeURIComponent(req.body.commenter)}`
|
|
|
+ },
|
|
|
+ "url": `http://skibidihub.buttplugstudios.xyz/video/${req.body.videoID}`,
|
|
|
+ "color": 917248
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ webhookURL
|
|
|
+ )
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+// Like a video
|
|
|
+app.post("/api/like/:id", async (req, res) => {
|
|
|
+ if(!utils.checkToken(req, "/api/like/:id")) return res.sendStatus(401);
|
|
|
+ if(!utils.videoExists(req.params.id)) return res.sendStatus(404);
|
|
|
+
|
|
|
+ const likesData = await client
|
|
|
+ .from("videos")
|
|
|
+ .select("likes")
|
|
|
+ .eq("id", req.params.id);
|
|
|
+
|
|
|
+ const likes = likesData["data"][0]["likes"] + 1;
|
|
|
+
|
|
|
+ const video = await client
|
|
|
+ .from("videos")
|
|
|
+ .update({ likes: likes })
|
|
|
+ .eq("id", req.params.id);
|
|
|
+
|
|
|
+ res.send(video);
|
|
|
+});
|
|
|
+
|
|
|
+// Dislike a video
|
|
|
+app.post("/api/dislike/:id", async (req, res) => {
|
|
|
+ if(!utils.checkToken(req, "/api/dislike/:id")) return res.sendStatus(401);
|
|
|
+ if(!utils.videoExists(req.params.id)) return res.sendStatus(404);
|
|
|
+
|
|
|
+ const dislikesData = await client
|
|
|
+ .from("videos")
|
|
|
+ .select("dislikes")
|
|
|
+ .eq("id", req.params.id);
|
|
|
+
|
|
|
+ const dislikes = dislikesData["data"][0]["dislikes"] + 1;
|
|
|
+
|
|
|
+ const video = await client
|
|
|
+ .from("videos")
|
|
|
+ .update({ dislikes: dislikes })
|
|
|
+ .eq("id", req.params.id);
|
|
|
+ res.send(video);
|
|
|
+});
|
|
|
+
|
|
|
+app.get("/api/userVideos/:id", async (req, res) => {
|
|
|
+ const data = await client
|
|
|
+ .from("videos")
|
|
|
+ .select()
|
|
|
+ .eq("uploader", decodeURIComponent(req.params.id));
|
|
|
+ res.send(data);
|
|
|
+});
|
|
|
+
|
|
|
+app.get("/api/sunset", async (req, res) => {
|
|
|
+ const file = fs.readFileSync(path.join(__dirname, "sunset.json"))
|
|
|
+ return res.send(JSON.parse(file))
|
|
|
+})
|
|
|
+
|
|
|
+app.post("/api/upload", upload.fields([
|
|
|
+ { name: 'video' }, { name: 'thumbnail' }
|
|
|
+]), utils.multerErrorHandler, async (req, res) => {
|
|
|
+ if(!utils.checkBodyVideo(req.body)) return res.status(400).json({ message: "invalid video body" });
|
|
|
+ if(!utils.checkToken(req, "/api/upload")) return res.status(401).json({ message: "SIGN IN to UPLOAD videos!!!" });
|
|
|
+
|
|
|
+ await client.from("videos").insert({
|
|
|
+ id: req.skibidihub_id,
|
|
|
+ likes: 0,
|
|
|
+ dislikes: 0,
|
|
|
+ description: req.body.description,
|
|
|
+ title: req.body.title,
|
|
|
+ uploader: req.body.uploader
|
|
|
+ }).then(data => {
|
|
|
+ res.status(201).json({
|
|
|
+ "id": req.skibidihub_id
|
|
|
+ })
|
|
|
+ // Discord webhook
|
|
|
+ utils.sendWebhook(
|
|
|
+ `new video guys <@&1274653503448678440> \`\`${req.skibidihub_id}\`\``,
|
|
|
+ "New UPLOAD!!!!",
|
|
|
+ [
|
|
|
+ {
|
|
|
+ "id": 220464536,
|
|
|
+ "description": req.body.description,
|
|
|
+ "fields": [],
|
|
|
+ "title": req.body.title,
|
|
|
+ "author": {
|
|
|
+ "name": req.body.uploader,
|
|
|
+ "url": `http://skibidihub.buttplugstudios.xyz/user/${encodeURIComponent(req.body.uploader)}`
|
|
|
+ },
|
|
|
+ "url": `http://skibidihub.buttplugstudios.xyz/video/${req.skibidihub_id}`,
|
|
|
+ "color": 9830655,
|
|
|
+ "image": {
|
|
|
+ "url": `https://skibidihub.buttplugstudios.xyz/api/webhookThumbnail/${req.skibidihub_id}`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ webhookURL
|
|
|
+ )
|
|
|
+ })
|
|
|
+})
|
|
|
+
|
|
|
+// Start App
|
|
|
+app.listen(port, () => {
|
|
|
+ console.log(`skibidihub listening on port ${port}`);
|
|
|
+});
|