mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-11 14:07:09 +03:00
consistent return and sendStatus
This commit is contained in:
@@ -9,15 +9,14 @@ import { Logger } from '../utils/logger';
|
||||
* https://support.google.com/youtube/answer/9230970
|
||||
*/
|
||||
|
||||
export function addUnlistedVideo(req: Request, res: Response): void {
|
||||
export function addUnlistedVideo(req: Request, res: Response): Response {
|
||||
const videoID = req.body.videoID;
|
||||
const year = req.body.year || 0;
|
||||
const views = req.body.views || 0;
|
||||
const channelID = req.body.channelID || "Unknown";
|
||||
|
||||
if (videoID === undefined || typeof(videoID) !== "string" || videoID.length !== 11) {
|
||||
res.status(400).send("Invalid parameters");
|
||||
return;
|
||||
return res.status(400).send("Invalid parameters");
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -25,9 +24,8 @@ export function addUnlistedVideo(req: Request, res: Response): void {
|
||||
db.prepare('run', `INSERT INTO "unlistedVideos" ("videoID", "year", "views", "channelID", "timeSubmitted") values (?, ?, ?, ?, ?)`, [videoID, year, views, channelID, timeSubmitted]);
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
|
||||
res.sendStatus(200);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import {db} from '../databases/databases';
|
||||
import {config} from '../config';
|
||||
import {Request, Response} from 'express';
|
||||
|
||||
export async function addUserAsVIP(req: Request, res: Response): Promise<void> {
|
||||
export async function addUserAsVIP(req: Request, res: Response): Promise<Response> {
|
||||
const userID = req.query.userID as string;
|
||||
let adminUserIDInput = req.query.adminUserID as string;
|
||||
|
||||
@@ -13,8 +13,7 @@ export async function addUserAsVIP(req: Request, res: Response): Promise<void> {
|
||||
|
||||
if (userID == undefined || adminUserIDInput == undefined) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -22,8 +21,7 @@ export async function addUserAsVIP(req: Request, res: Response): Promise<void> {
|
||||
|
||||
if (adminUserIDInput !== config.adminUserID) {
|
||||
//not authorized
|
||||
res.sendStatus(403);
|
||||
return;
|
||||
return res.sendStatus(403);
|
||||
}
|
||||
|
||||
//check to see if this user is already a vip
|
||||
@@ -37,5 +35,5 @@ export async function addUserAsVIP(req: Request, res: Response): Promise<void> {
|
||||
await db.prepare('run', 'DELETE FROM "vipUsers" WHERE "userID" = ?', [userID]);
|
||||
}
|
||||
|
||||
res.sendStatus(200);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import {db} from '../databases/databases';
|
||||
import { Category, VideoID } from '../types/segments.model';
|
||||
import { UserID } from '../types/user.model';
|
||||
|
||||
export async function deleteLockCategoriesEndpoint(req: Request, res: Response): Promise<void> {
|
||||
export async function deleteLockCategoriesEndpoint(req: Request, res: Response): Promise<Response> {
|
||||
// Collect user input data
|
||||
const videoID = req.body.videoID as VideoID;
|
||||
const userID = req.body.userID as UserID;
|
||||
@@ -18,10 +18,9 @@ export async function deleteLockCategoriesEndpoint(req: Request, res: Response):
|
||||
|| !Array.isArray(categories)
|
||||
|| categories.length === 0
|
||||
) {
|
||||
res.status(400).json({
|
||||
return res.status(400).json({
|
||||
message: 'Bad Format',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user is VIP
|
||||
@@ -29,15 +28,14 @@ export async function deleteLockCategoriesEndpoint(req: Request, res: Response):
|
||||
const userIsVIP = await isUserVIP(hashedUserID);
|
||||
|
||||
if (!userIsVIP) {
|
||||
res.status(403).json({
|
||||
return res.status(403).json({
|
||||
message: 'Must be a VIP to mark videos.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await deleteLockCategories(videoID, categories);
|
||||
|
||||
res.status(200).json({message: 'Removed lock categories entrys for video ' + videoID});
|
||||
return res.status(200).json({message: 'Removed lock categories entrys for video ' + videoID});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -181,7 +181,7 @@ export async function redirectLink(req: Request, res: Response): Promise<void> {
|
||||
if (file) {
|
||||
res.redirect("/download/" + file.fileName);
|
||||
} else {
|
||||
res.status(404).send();
|
||||
res.sendStatus(404);
|
||||
}
|
||||
|
||||
await queueDump();
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import {db} from '../databases/databases';
|
||||
import {Request, Response} from 'express';
|
||||
|
||||
export async function getDaysSavedFormatted(req: Request, res: Response): Promise<void> {
|
||||
export async function getDaysSavedFormatted(req: Request, res: Response): Promise<Response> {
|
||||
const row = await db.prepare('get', 'SELECT SUM(("endTime" - "startTime") / 60 / 60 / 24 * "views") as "daysSaved" from "sponsorTimes" where "shadowHidden" != 1', []);
|
||||
|
||||
if (row !== undefined) {
|
||||
//send this result
|
||||
res.send({
|
||||
return res.send({
|
||||
daysSaved: row.daysSaved.toFixed(2),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@ import {isUserVIP} from '../utils/isUserVIP';
|
||||
import {Request, Response} from 'express';
|
||||
import { HashedUserID, UserID } from '../types/user.model';
|
||||
|
||||
export async function getIsUserVIP(req: Request, res: Response): Promise<void> {
|
||||
export async function getIsUserVIP(req: Request, res: Response): Promise<Response> {
|
||||
const userID = req.query.userID as UserID;
|
||||
|
||||
if (userID == undefined) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -18,14 +17,12 @@ export async function getIsUserVIP(req: Request, res: Response): Promise<void> {
|
||||
|
||||
try {
|
||||
const vipState = await isUserVIP(hashedUserID);
|
||||
res.status(200).json({
|
||||
return res.status(200).json({
|
||||
hashedUserID: hashedUserID,
|
||||
vip: vipState,
|
||||
});
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
res.sendStatus(500);
|
||||
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,12 @@ import { Logger } from '../utils/logger';
|
||||
|
||||
const maxRewardTimePerSegmentInSeconds = config.maxRewardTimePerSegmentInSeconds ?? 86400;
|
||||
|
||||
export async function getSavedTimeForUser(req: Request, res: Response): Promise<void> {
|
||||
export async function getSavedTimeForUser(req: Request, res: Response): Promise<Response> {
|
||||
let userID = req.query.userID as string;
|
||||
|
||||
if (userID == undefined) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -22,16 +21,14 @@ export async function getSavedTimeForUser(req: Request, res: Response): Promise<
|
||||
const row = await db.prepare("get", 'SELECT SUM(((CASE WHEN "endTime" - "startTime" > ? THEN ? ELSE "endTime" - "startTime" END) / 60) * "views") as "minutesSaved" FROM "sponsorTimes" WHERE "userID" = ? AND "votes" > -1 AND "shadowHidden" != 1 ', [maxRewardTimePerSegmentInSeconds, maxRewardTimePerSegmentInSeconds, userID]);
|
||||
|
||||
if (row.minutesSaved != null) {
|
||||
res.send({
|
||||
return res.send({
|
||||
timeSaved: row.minutesSaved,
|
||||
});
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error("getSavedTimeForUser " + err);
|
||||
res.sendStatus(500);
|
||||
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,19 +57,19 @@ async function handleGetSegmentInfo(req: Request, res: Response): Promise<DBSegm
|
||||
return DBSegments;
|
||||
}
|
||||
|
||||
async function endpoint(req: Request, res: Response): Promise<void> {
|
||||
async function endpoint(req: Request, res: Response): Promise<Response> {
|
||||
try {
|
||||
const DBSegments = await handleGetSegmentInfo(req, res);
|
||||
|
||||
// If false, res.send has already been called
|
||||
if (DBSegments) {
|
||||
//send result
|
||||
res.send(DBSegments);
|
||||
return res.send(DBSegments);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof SyntaxError) { // catch JSON.parse error
|
||||
res.status(400).send("UUIDs parameter does not match format requirements.");
|
||||
} else res.status(500).send();
|
||||
return res.status(400).send("UUIDs parameter does not match format requirements.");
|
||||
} else return res.sendStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -291,26 +291,25 @@ async function handleGetSegments(req: Request, res: Response): Promise<Segment[]
|
||||
|
||||
if (segments.length === 0) {
|
||||
res.sendStatus(404);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
async function endpoint(req: Request, res: Response): Promise<void> {
|
||||
async function endpoint(req: Request, res: Response): Promise<Response> {
|
||||
try {
|
||||
const segments = await handleGetSegments(req, res);
|
||||
|
||||
// If false, res.send has already been called
|
||||
if (segments) {
|
||||
//send result
|
||||
res.send(segments);
|
||||
return res.send(segments);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err instanceof SyntaxError) {
|
||||
res.status(400).send("Categories parameter does not match format requirements.");
|
||||
} else res.status(500).send();
|
||||
return res.status(400).send("Categories parameter does not match format requirements.");
|
||||
} else return res.sendStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,8 +69,7 @@ export async function getTopUsers(req: Request, res: Response): Promise<Response
|
||||
|
||||
if (sortType == undefined) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//setup which sort type to use
|
||||
|
||||
@@ -88,19 +88,18 @@ async function dbGetLastSegmentForUser(userID: HashedUserID): Promise<SegmentUUI
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUserInfo(req: Request, res: Response): Promise<void> {
|
||||
export async function getUserInfo(req: Request, res: Response): Promise<Response> {
|
||||
const userID = req.query.userID as UserID;
|
||||
const hashedUserID: HashedUserID = userID ? getHash(userID) : req.query.publicUserID as HashedUserID;
|
||||
|
||||
if (hashedUserID == undefined) {
|
||||
//invalid request
|
||||
res.status(400).send('Parameters are not valid');
|
||||
return;
|
||||
return res.status(400).send('Parameters are not valid');
|
||||
}
|
||||
|
||||
const segmentsSummary = await dbGetSubmittedSegmentSummary(hashedUserID);
|
||||
if (segmentsSummary) {
|
||||
res.send({
|
||||
return res.send({
|
||||
userID: hashedUserID,
|
||||
userName: await dbGetUsername(hashedUserID),
|
||||
minutesSaved: segmentsSummary.minutesSaved,
|
||||
@@ -114,6 +113,6 @@ export async function getUserInfo(req: Request, res: Response): Promise<void> {
|
||||
lastSegmentID: await dbGetLastSegmentForUser(hashedUserID),
|
||||
});
|
||||
} else {
|
||||
res.status(400).send();
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,12 @@ import {getHash} from '../utils/getHash';
|
||||
import {Logger} from '../utils/logger';
|
||||
import {Request, Response} from 'express';
|
||||
|
||||
export async function getUsername(req: Request, res: Response): Promise<void> {
|
||||
export async function getUsername(req: Request, res: Response): Promise<Response> {
|
||||
let userID = req.query.userID as string;
|
||||
|
||||
if (userID == undefined) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -19,18 +18,17 @@ export async function getUsername(req: Request, res: Response): Promise<void> {
|
||||
const row = await db.prepare('get', `SELECT "userName" FROM "userNames" WHERE "userID" = ?`, [userID]);
|
||||
|
||||
if (row !== undefined) {
|
||||
res.send({
|
||||
return res.send({
|
||||
userName: row.userName,
|
||||
});
|
||||
} else {
|
||||
//no username yet, just send back the userID
|
||||
res.send({
|
||||
return res.send({
|
||||
userName: userID,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,12 @@ import {Request, Response} from 'express';
|
||||
import {getHash} from '../utils/getHash';
|
||||
import {Logger} from '../utils/logger';
|
||||
|
||||
export async function getViewsForUser(req: Request, res: Response): Promise<void> {
|
||||
export async function getViewsForUser(req: Request, res: Response): Promise<Response> {
|
||||
let userID = req.query.userID as string;
|
||||
|
||||
if (userID == undefined) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -20,15 +19,14 @@ export async function getViewsForUser(req: Request, res: Response): Promise<void
|
||||
|
||||
//increase the view count by one
|
||||
if (row.viewCount != null) {
|
||||
res.send({
|
||||
return res.send({
|
||||
viewCount: row.viewCount,
|
||||
});
|
||||
} else {
|
||||
res.sendStatus(404);
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {handleGetSegments} from './getSkipSegments';
|
||||
import {Request, Response} from 'express';
|
||||
|
||||
export async function oldGetVideoSponsorTimes(req: Request, res: Response): Promise<void> {
|
||||
export async function oldGetVideoSponsorTimes(req: Request, res: Response): Promise<Response> {
|
||||
const segments = await handleGetSegments(req, res);
|
||||
|
||||
if (segments) {
|
||||
@@ -14,7 +14,7 @@ export async function oldGetVideoSponsorTimes(req: Request, res: Response): Prom
|
||||
UUIDs.push(segment.UUID);
|
||||
}
|
||||
|
||||
res.send({
|
||||
return res.send({
|
||||
sponsorTimes,
|
||||
UUIDs,
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {postSkipSegments} from './postSkipSegments';
|
||||
import {Request, Response} from 'express';
|
||||
|
||||
export async function oldSubmitSponsorTimes(req: Request, res: Response): Promise<void> {
|
||||
export async function oldSubmitSponsorTimes(req: Request, res: Response): Promise<Response> {
|
||||
req.query.category = "sponsor";
|
||||
return postSkipSegments(req, res);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { QueryCacher } from '../utils/queryCacher';
|
||||
import { isUserVIP } from '../utils/isUserVIP';
|
||||
import { VideoIDHash } from "../types/segments.model";
|
||||
|
||||
export async function postClearCache(req: Request, res: Response): Promise<void> {
|
||||
export async function postClearCache(req: Request, res: Response): Promise<Response> {
|
||||
const videoID = req.query.videoID as VideoID;
|
||||
const userID = req.query.userID as UserID;
|
||||
const service = req.query.service as Service ?? Service.YouTube;
|
||||
@@ -23,8 +23,7 @@ export async function postClearCache(req: Request, res: Response): Promise<void>
|
||||
if (invalidFields.length !== 0) {
|
||||
// invalid request
|
||||
const fields = invalidFields.reduce((p, c, i) => p + (i !== 0 ? ', ' : '') + c, '');
|
||||
res.status(400).send(`No valid ${fields} field(s) provided`);
|
||||
return;
|
||||
return res.status(400).send(`No valid ${fields} field(s) provided`);
|
||||
}
|
||||
|
||||
// hash the userID as early as possible
|
||||
@@ -35,8 +34,7 @@ export async function postClearCache(req: Request, res: Response): Promise<void>
|
||||
// Ensure user is a VIP
|
||||
if (!(await isUserVIP(hashedUserID))){
|
||||
Logger.warn("Permission violation: User " + hashedUserID + " attempted to clear cache for video " + videoID + ".");
|
||||
res.status(403).json({"message": "Not a VIP"});
|
||||
return;
|
||||
return res.status(403).json({"message": "Not a VIP"});
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -45,11 +43,10 @@ export async function postClearCache(req: Request, res: Response): Promise<void>
|
||||
hashedVideoID,
|
||||
service
|
||||
});
|
||||
res.status(200).json({
|
||||
return res.status(200).json({
|
||||
message: "Cache cleared on video " + videoID
|
||||
});
|
||||
} catch(err) {
|
||||
res.status(500).send();
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,13 @@ import {HashedUserID, UserID} from '../types/user.model';
|
||||
import {VideoID} from "../types/segments.model";
|
||||
import {db} from '../databases/databases';
|
||||
|
||||
export async function postPurgeAllSegments(req: Request, res: Response): Promise<void> {
|
||||
export async function postPurgeAllSegments(req: Request, res: Response): Promise<Response> {
|
||||
const userID = req.body.userID as UserID;
|
||||
const videoID = req.body.videoID as VideoID;
|
||||
|
||||
if (userID == undefined) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -22,20 +21,16 @@ export async function postPurgeAllSegments(req: Request, res: Response): Promise
|
||||
try {
|
||||
const vipState = await isUserVIP(hashedUserID);
|
||||
if (!vipState) {
|
||||
res.status(403).json({
|
||||
return res.status(403).json({
|
||||
message: 'Must be a VIP to perform this action.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await db.prepare('run', `UPDATE "sponsorTimes" SET "hidden" = 1 WHERE "videoID" = ?`, [videoID]);
|
||||
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
res.sendStatus(500);
|
||||
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
|
||||
res.sendStatus(200);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
@@ -58,10 +58,9 @@ export async function postSegmentShift(req: Request, res: Response): Promise<Res
|
||||
|| !startTime
|
||||
|| !endTime
|
||||
) {
|
||||
res.status(400).json({
|
||||
return res.status(400).json({
|
||||
message: 'Bad Format',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if user is VIP
|
||||
@@ -69,10 +68,9 @@ export async function postSegmentShift(req: Request, res: Response): Promise<Res
|
||||
const userIsVIP = await isUserVIP(userID);
|
||||
|
||||
if (!userIsVIP) {
|
||||
res.status(403).json({
|
||||
return res.status(403).json({
|
||||
message: 'Must be a VIP to perform this action.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -95,8 +93,8 @@ export async function postSegmentShift(req: Request, res: Response): Promise<Res
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
res.sendStatus(500);
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
|
||||
res.sendStatus(200);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ function proxySubmission(req: Request) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function postSkipSegments(req: Request, res: Response): Promise<void> {
|
||||
export async function postSkipSegments(req: Request, res: Response): Promise<Response> {
|
||||
if (config.proxySubmission) {
|
||||
proxySubmission(req);
|
||||
}
|
||||
@@ -315,8 +315,7 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
if (invalidFields.length !== 0) {
|
||||
// invalid request
|
||||
const fields = invalidFields.reduce((p, c, i) => p + (i !== 0 ? ', ' : '') + c, '');
|
||||
res.status(400).send(`No valid ${fields} field(s) provided`);
|
||||
return;
|
||||
return res.status(400).send(`No valid ${fields} field(s) provided`);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -332,13 +331,10 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
)).count;
|
||||
|
||||
if (warningsCount >= config.maxNumberOfActiveWarnings) {
|
||||
res.status(403).send('Submission rejected due to a warning from a moderator. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. Could you please send a message in Discord or Matrix so we can further help you?');
|
||||
return;
|
||||
return res.status(403).send('Submission rejected due to a warning from a moderator. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. Could you please send a message in Discord or Matrix so we can further help you?');
|
||||
}
|
||||
|
||||
let lockedCategoryList = (await db.prepare('all', 'SELECT category from "lockCategories" where "videoID" = ?', [videoID])).map((list: any) => {
|
||||
return list.category;
|
||||
});
|
||||
let lockedCategoryList = (await db.prepare('all', 'SELECT category from "lockCategories" where "videoID" = ?', [videoID])).map((list: any) => list.category );
|
||||
|
||||
//check if this user is on the vip list
|
||||
const isVIP = (await db.prepare("get", `SELECT count(*) as "userCount" FROM "vipUsers" WHERE "userID" = ?`, [userID])).userCount > 0;
|
||||
@@ -377,27 +373,24 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
if (segments[i] === undefined || segments[i].segment === undefined || segments[i].category === undefined) {
|
||||
//invalid request
|
||||
res.status(400).send("One of your segments are invalid");
|
||||
return;
|
||||
return res.status(400).send("One of your segments are invalid");
|
||||
}
|
||||
|
||||
if (!config.categoryList.includes(segments[i].category)) {
|
||||
res.status(400).send("Category doesn't exist.");
|
||||
return;
|
||||
return res.status(400).send("Category doesn't exist.");
|
||||
}
|
||||
|
||||
// Reject segment if it's in the locked categories list
|
||||
if (!isVIP && lockedCategoryList.indexOf(segments[i].category) !== -1) {
|
||||
// TODO: Do something about the fradulent submission
|
||||
Logger.warn("Caught a no-segment submission. userID: '" + userID + "', videoID: '" + videoID + "', category: '" + segments[i].category + "'");
|
||||
res.status(403).send(
|
||||
return res.status(403).send(
|
||||
"New submissions are not allowed for the following category: '"
|
||||
+ segments[i].category + "'. A moderator has decided that no new segments are needed and that all current segments of this category are timed perfectly.\n\n "
|
||||
+ (segments[i].category === "sponsor" ? "Maybe the segment you are submitting is a different category that you have not enabled and is not a sponsor. " +
|
||||
"Categories that aren't sponsor, such as self-promotion can be enabled in the options.\n\n" : "")
|
||||
+ "If you believe this is incorrect, please contact someone on discord.gg/SponsorBlock or matrix.to/#/+sponsorblock:ajay.app",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -409,22 +402,19 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
|| (getCategoryActionType(segments[i].category) === CategoryActionType.Skippable && startTime === endTime)
|
||||
|| (getCategoryActionType(segments[i].category) === CategoryActionType.POI && startTime !== endTime)) {
|
||||
//invalid request
|
||||
res.status(400).send("One of your segments times are invalid (too short, startTime before endTime, etc.)");
|
||||
return;
|
||||
return res.status(400).send("One of your segments times are invalid (too short, startTime before endTime, etc.)");
|
||||
}
|
||||
|
||||
if (!isVIP && segments[i].category === "sponsor" && Math.abs(startTime - endTime) < 1) {
|
||||
// Too short
|
||||
res.status(400).send("Sponsors must be longer than 1 second long");
|
||||
return;
|
||||
return res.status(400).send("Sponsors must be longer than 1 second long");
|
||||
}
|
||||
|
||||
//check if this info has already been submitted before
|
||||
const duplicateCheck2Row = await db.prepare('get', `SELECT COUNT(*) as count FROM "sponsorTimes" WHERE "startTime" = ?
|
||||
and "endTime" = ? and "category" = ? and "videoID" = ? and "service" = ?`, [startTime, endTime, segments[i].category, videoID, service]);
|
||||
if (duplicateCheck2Row.count > 0) {
|
||||
res.sendStatus(409);
|
||||
return;
|
||||
return res.sendStatus(409);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,8 +429,7 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
//decreaseVotes = -2; //Disable for now
|
||||
} else if (autoModerateResult) {
|
||||
//Normal automod behavior
|
||||
res.status(403).send("Request rejected by auto moderator: " + autoModerateResult + " If this is an issue, send a message on Discord.");
|
||||
return;
|
||||
return res.status(403).send("Request rejected by auto moderator: " + autoModerateResult + " If this is an issue, send a message on Discord.");
|
||||
}
|
||||
}
|
||||
// Will be filled when submitting
|
||||
@@ -461,8 +450,7 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
|
||||
if (rateLimitCheckRow.count >= 10) {
|
||||
//too many sponsors for the same video from the same ip address
|
||||
res.sendStatus(429);
|
||||
return;
|
||||
return res.sendStatus(429);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,8 +462,7 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
|
||||
if (duplicateCheckRow.count >= 16) {
|
||||
//too many sponsors for the same video from the same user
|
||||
res.sendStatus(429);
|
||||
return;
|
||||
return res.sendStatus(429);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,10 +507,9 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
});
|
||||
} catch (err) {
|
||||
//a DB change probably occurred
|
||||
res.sendStatus(500);
|
||||
Logger.error("Error when putting sponsorTime in the DB: " + videoID + ", " + segmentInfo.segment[0] + ", " +
|
||||
segmentInfo.segment[1] + ", " + userID + ", " + segmentInfo.category + ". " + err);
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
|
||||
UUIDs.push(UUID);
|
||||
@@ -535,15 +521,13 @@ export async function postSkipSegments(req: Request, res: Response): Promise<voi
|
||||
}
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
|
||||
res.json(newSegments);
|
||||
|
||||
for (let i = 0; i < segments.length; i++) {
|
||||
sendWebhooks(apiVideoInfo, userID, videoID, UUIDs[i], segments[i], service);
|
||||
}
|
||||
return res.json(newSegments);
|
||||
}
|
||||
|
||||
// Takes an array of arrays:
|
||||
|
||||
@@ -5,7 +5,7 @@ import {isUserVIP} from '../utils/isUserVIP';
|
||||
import {getHash} from '../utils/getHash';
|
||||
import { HashedUserID, UserID } from '../types/user.model';
|
||||
|
||||
export async function postWarning(req: Request, res: Response): Promise<void> {
|
||||
export async function postWarning(req: Request, res: Response): Promise<Response> {
|
||||
// Collect user input data
|
||||
const issuerUserID: HashedUserID = getHash(<UserID> req.body.issuerUserID);
|
||||
const userID: UserID = req.body.userID;
|
||||
@@ -16,8 +16,7 @@ export async function postWarning(req: Request, res: Response): Promise<void> {
|
||||
// Ensure user is a VIP
|
||||
if (!await isUserVIP(issuerUserID)) {
|
||||
Logger.warn("Permission violation: User " + issuerUserID + " attempted to warn user " + userID + ".");
|
||||
res.status(403).json({"message": "Not a VIP"});
|
||||
return;
|
||||
return res.status(403).json({"message": "Not a VIP"});
|
||||
}
|
||||
|
||||
let resultStatus = "";
|
||||
@@ -33,15 +32,14 @@ export async function postWarning(req: Request, res: Response): Promise<void> {
|
||||
);
|
||||
resultStatus = "issued to";
|
||||
} else {
|
||||
res.status(409).send();
|
||||
return;
|
||||
return res.sendStatus(409);
|
||||
}
|
||||
} else {
|
||||
await db.prepare('run', 'UPDATE "warnings" SET "enabled" = 0 WHERE "userID" = ?', [userID]);
|
||||
resultStatus = "removed from";
|
||||
}
|
||||
|
||||
res.status(200).json({
|
||||
return res.status(200).json({
|
||||
message: "Warning " + resultStatus + " user '" + userID + "'.",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,14 +4,14 @@ import {db, privateDB} from '../databases/databases';
|
||||
import {getHash} from '../utils/getHash';
|
||||
import {Request, Response} from 'express';
|
||||
|
||||
async function logUserNameChange(userID: string, newUserName: string, oldUserName: string, updatedByAdmin: boolean): Promise<void> {
|
||||
async function logUserNameChange(userID: string, newUserName: string, oldUserName: string, updatedByAdmin: boolean): Promise<Response> {
|
||||
return privateDB.prepare('run',
|
||||
`INSERT INTO "userNameLogs"("userID", "newUserName", "oldUserName", "updatedByAdmin", "updatedAt") VALUES(?, ?, ?, ?, ?)`,
|
||||
[userID, newUserName, oldUserName, + updatedByAdmin, new Date().getTime()]
|
||||
);
|
||||
}
|
||||
|
||||
export async function setUsername(req: Request, res: Response): Promise<void> {
|
||||
export async function setUsername(req: Request, res: Response): Promise<Response> {
|
||||
let userID = req.query.userID as string;
|
||||
let userName = req.query.username as string;
|
||||
|
||||
@@ -19,14 +19,12 @@ export async function setUsername(req: Request, res: Response): Promise<void> {
|
||||
|
||||
if (userID == undefined || userName == undefined || userID === "undefined" || userName.length > 64) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
if (userName.includes("discord")) {
|
||||
// Don't allow
|
||||
res.sendStatus(200);
|
||||
return;
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
// remove unicode control characters from username (example: \n, \r, \t etc.)
|
||||
@@ -40,8 +38,7 @@ export async function setUsername(req: Request, res: Response): Promise<void> {
|
||||
|
||||
if (adminUserIDInput != config.adminUserID) {
|
||||
//they aren't the admin
|
||||
res.sendStatus(403);
|
||||
return;
|
||||
return res.sendStatus(403);
|
||||
}
|
||||
} else {
|
||||
//hash the userID
|
||||
@@ -51,14 +48,12 @@ export async function setUsername(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const row = await db.prepare('get', `SELECT count(*) as count FROM "userNames" WHERE "userID" = ? AND "locked" = '1'`, [userID]);
|
||||
if (adminUserIDInput === undefined && row.count > 0) {
|
||||
res.sendStatus(200);
|
||||
return;
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
Logger.error(error);
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -78,10 +73,9 @@ export async function setUsername(req: Request, res: Response): Promise<void> {
|
||||
|
||||
await logUserNameChange(userID, userName, oldUserName, adminUserIDInput !== undefined);
|
||||
|
||||
res.sendStatus(200);
|
||||
return res.sendStatus(200);
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
res.sendStatus(500);
|
||||
return;
|
||||
return res.sendStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Category, Service, VideoID, VideoIDHash } from '../types/segments.model
|
||||
import { UserID } from '../types/user.model';
|
||||
import { QueryCacher } from '../utils/queryCacher';
|
||||
|
||||
export async function shadowBanUser(req: Request, res: Response): Promise<void> {
|
||||
export async function shadowBanUser(req: Request, res: Response): Promise<Response> {
|
||||
const userID = req.query.userID as string;
|
||||
const hashedIP = req.query.hashedIP as string;
|
||||
let adminUserIDInput = req.query.adminUserID as string;
|
||||
@@ -23,8 +23,7 @@ export async function shadowBanUser(req: Request, res: Response): Promise<void>
|
||||
|
||||
if (adminUserIDInput == undefined || (userID == undefined && hashedIP == undefined)) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -33,8 +32,7 @@ export async function shadowBanUser(req: Request, res: Response): Promise<void>
|
||||
const isVIP = (await db.prepare("get", `SELECT count(*) as "userCount" FROM "vipUsers" WHERE "userID" = ?`, [adminUserIDInput])).userCount > 0;
|
||||
if (!isVIP) {
|
||||
//not authorized
|
||||
res.sendStatus(403);
|
||||
return;
|
||||
return res.sendStatus(403);
|
||||
}
|
||||
|
||||
if (userID) {
|
||||
@@ -114,6 +112,5 @@ export async function shadowBanUser(req: Request, res: Response): Promise<void>
|
||||
// }
|
||||
}*/
|
||||
}
|
||||
|
||||
res.sendStatus(200);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
@@ -161,31 +161,27 @@ async function sendWebhooks(voteData: VoteData) {
|
||||
}
|
||||
|
||||
async function categoryVote(UUID: SegmentUUID, userID: UserID, isVIP: boolean, isOwnSubmission: boolean, category: Category
|
||||
, hashedIP: HashedIP, finalResponse: FinalResponse, res: Response) {
|
||||
, hashedIP: HashedIP, finalResponse: FinalResponse, res: Response): Promise<Response> {
|
||||
// Check if they've already made a vote
|
||||
const usersLastVoteInfo = await privateDB.prepare('get', `select count(*) as votes, category from "categoryVotes" where "UUID" = ? and "userID" = ? group by category`, [UUID, userID]);
|
||||
|
||||
if (usersLastVoteInfo?.category === category) {
|
||||
// Double vote, ignore
|
||||
res.sendStatus(finalResponse.finalStatus);
|
||||
return;
|
||||
return res.sendStatus(finalResponse.finalStatus);
|
||||
}
|
||||
|
||||
const videoInfo = (await db.prepare('get', `SELECT "category", "videoID", "hashedVideoID", "service", "userID" FROM "sponsorTimes" WHERE "UUID" = ?`,
|
||||
[UUID])) as {category: Category, videoID: VideoID, hashedVideoID: VideoIDHash, service: Service, userID: UserID};
|
||||
if (!videoInfo) {
|
||||
// Submission doesn't exist
|
||||
res.status(400).send("Submission doesn't exist.");
|
||||
return;
|
||||
return res.status(400).send("Submission doesn't exist.");
|
||||
}
|
||||
|
||||
if (!config.categoryList.includes(category)) {
|
||||
res.status(400).send("Category doesn't exist.");
|
||||
return;
|
||||
return res.status(400).send("Category doesn't exist.");
|
||||
}
|
||||
if (getCategoryActionType(category) !== CategoryActionType.Skippable) {
|
||||
res.status(400).send("Cannot vote for this category");
|
||||
return;
|
||||
return res.status(400).send("Cannot vote for this category");
|
||||
}
|
||||
|
||||
const nextCategoryInfo = await db.prepare("get", `select votes from "categoryVotes" where "UUID" = ? and category = ?`, [UUID, category]);
|
||||
@@ -245,14 +241,14 @@ async function categoryVote(UUID: SegmentUUID, userID: UserID, isVIP: boolean, i
|
||||
|
||||
QueryCacher.clearVideoCache(videoInfo);
|
||||
|
||||
res.sendStatus(finalResponse.finalStatus);
|
||||
return res.sendStatus(finalResponse.finalStatus);
|
||||
}
|
||||
|
||||
export function getUserID(req: Request): UserID {
|
||||
return req.query.userID as UserID;
|
||||
}
|
||||
|
||||
export async function voteOnSponsorTime(req: Request, res: Response): Promise<void> {
|
||||
export async function voteOnSponsorTime(req: Request, res: Response): Promise<Response> {
|
||||
const UUID = req.query.UUID as SegmentUUID;
|
||||
const paramUserID = getUserID(req);
|
||||
let type = req.query.type !== undefined ? parseInt(req.query.type as string) : undefined;
|
||||
@@ -260,8 +256,7 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<vo
|
||||
|
||||
if (UUID === undefined || paramUserID === undefined || (type === undefined && category === undefined)) {
|
||||
//invalid request
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
//hash the userID
|
||||
@@ -292,8 +287,7 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<vo
|
||||
// disallow vote types 10/11
|
||||
if (type === 10 || type === 11) {
|
||||
// no longer allow type 10/11 alternative votes
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
|
||||
// If not upvote
|
||||
@@ -320,12 +314,10 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<vo
|
||||
|
||||
if (voteInfo && voteInfo.votes <= -2) {
|
||||
if (type == 1) {
|
||||
res.status(403).send("Not allowed to upvote segment with too many downvotes unless you are VIP.");
|
||||
return;
|
||||
return res.status(403).send("Not allowed to upvote segment with too many downvotes unless you are VIP.");
|
||||
} else if (type == 0) {
|
||||
// Already downvoted enough, ignore
|
||||
res.status(200).send();
|
||||
return;
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,8 +329,7 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<vo
|
||||
)).count;
|
||||
|
||||
if (warningsCount >= config.maxNumberOfActiveWarnings) {
|
||||
res.status(403).send('Vote rejected due to a warning from a moderator. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. Could you please send a message in Discord or Matrix so we can further help you?');
|
||||
return;
|
||||
return res.status(403).send('Vote rejected due to a warning from a moderator. This means that we noticed you were making some common mistakes that are not malicious, and we just want to clarify the rules. Could you please send a message in Discord or Matrix so we can further help you?');
|
||||
}
|
||||
|
||||
const voteTypeEnum = (type == 0 || type == 1 || type == 20) ? voteTypes.normal : voteTypes.incorrect;
|
||||
@@ -362,8 +353,7 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<vo
|
||||
incrementAmount = 0;
|
||||
} else {
|
||||
//unrecongnised type of vote
|
||||
res.sendStatus(400);
|
||||
return;
|
||||
return res.sendStatus(400);
|
||||
}
|
||||
if (votesRow != undefined) {
|
||||
if (votesRow.type === 1) {
|
||||
@@ -445,9 +435,6 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<vo
|
||||
|
||||
QueryCacher.clearVideoCache(videoInfo);
|
||||
}
|
||||
|
||||
res.status(finalResponse.finalStatus).send(finalResponse.finalMessage ?? undefined);
|
||||
|
||||
if (incrementAmount - oldIncrementAmount !== 0) {
|
||||
sendWebhooks({
|
||||
UUID,
|
||||
@@ -462,9 +449,9 @@ export async function voteOnSponsorTime(req: Request, res: Response): Promise<vo
|
||||
finalResponse
|
||||
});
|
||||
}
|
||||
return res.status(finalResponse.finalStatus).send(finalResponse.finalMessage ?? undefined);
|
||||
} catch (err) {
|
||||
Logger.error(err);
|
||||
|
||||
res.status(500).json({error: 'Internal error creating segment vote'});
|
||||
return res.status(500).json({error: 'Internal error creating segment vote'});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user